1 /-
2 Copyright (c) 2018 Mario Carneiro. All rights reserved.
3 Released under Apache 2.0 license as described in the file LICENSE.
4 Author: Mario Carneiro
5
6 The primitive recursive functions are the least collection of functions
7 nat → nat which are closed under projections (using the mkpair
8 pairing function), composition, zero, successor, and primitive recursion
9 (i.e. nat.rec where the motive is C n := nat).
10
11 We can extend this definition to a large class of basic types by
12 using canonical encodings of types as natural numbers (Gödel numbering),
13 which we implement through the type class `encodable`. (More precisely,
14 we need that the composition of encode with decode yields a
15 primitive recursive function, so we have the `primcodable` type class
16 for this.)
17 -/
18 import data.equiv.list
src └─────────────┘
19
20 open denumerable encodable
21
22 namespace nat
23
24 def elim {C : Sort*} : C → (ℕ → C → C) → ℕ → C := @nat.rec (λ _, C)
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─────┘ ┴ ┴
src ┴ ┴ └─────┘
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─────┘ ┴ ┴
25
26 @[simp] theorem elim_zero {C} (a f) : @nat.elim C a f 0 = a := rfl
id └──────┘ ┴ ┴ ┴ ┴ ┴ └─┘
src └──────┘ ┴ └─┘
typ └──────┘ ┴ ┴ ┴ ┴ ┴ └─┘
doc └──┘
27 @[simp] theorem elim_succ {C} (a f n) :
doc └──┘
28 @nat.elim C a f (succ n) = f n (nat.elim a f n) := rfl
id └──────┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ └─┘
src └──────┘ └──┘ ┴ └──────┘ └─┘
typ └──────┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ └─┘
29
30 def cases {C : Sort*} (a : C) (f : ℕ → C) : ℕ → C := nat.elim a (λ n _, f n)
id ┴ ┴ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ ┴ ┴
src ┴ ┴ └──────┘
typ ┴ ┴ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ ┴ ┴
31
32 @[simp] theorem cases_zero {C} (a f) : @nat.cases C a f 0 = a := rfl
id └───────┘ ┴ ┴ ┴ ┴ ┴ └─┘
src └───────┘ ┴ └─┘
typ └───────┘ ┴ ┴ ┴ ┴ ┴ └─┘
doc └──┘
33 @[simp] theorem cases_succ {C} (a f n) : @nat.cases C a f (succ n) = f n := rfl
id └───────┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ └─┘
src └───────┘ └──┘ ┴ └─┘
typ └───────┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ └─┘
doc └──┘
34
35 @[simp, reducible] def unpaired {α} (f : ℕ → ℕ → α) (n : ℕ) : α :=
id ┴ ┴ ┴ ┴ ┴
src ┴ ┴ ┴
typ ┴ ┴ ┴ ┴ ┴
doc └──┘ └───────┘
36 f n.unpair.1 n.unpair.2
id ┴ ┴└─────┘┴ ┴└─────┘┴
src └─────┘┴ └─────┘┴
typ ┴ ┴└─────┘┴ ┴└─────┘┴
doc └─────┘ └─────┘
37
38 /-- The primitive recursive functions `ℕ → ℕ`. -/
39 inductive primrec : (ℕ → ℕ) → Prop
id ┴ ┴ ┴
src ┴ ┴
typ ┴ ┴ ┴
40 | zero : primrec (λ n, 0)
id ┴
typ ┴
41 | succ : primrec succ
id └──┘
src └──┘
typ └──┘
42 | left : primrec (λ n, n.unpair.1)
id ┴ ┴└─────┘┴
src └─────┘┴
typ ┴ ┴└─────┘┴
doc └─────┘
43 | right : primrec (λ n, n.unpair.2)
id ┴ ┴└─────┘┴
src └─────┘┴
typ ┴ ┴└─────┘┴
doc └─────┘
44 | pair {f g} : primrec f → primrec g → primrec (λ n, mkpair (f n) (g n))
id ┴ ┴ └─────┘ ┴ └─────┘ ┴ ┴ └────┘ ┴ ┴ ┴ ┴
src └────┘
typ ┴ ┴ └─────┘ ┴ └─────┘ ┴ ┴ └────┘ ┴ ┴ ┴ ┴
doc └────┘
45 | comp {f g} : primrec f → primrec g → primrec (λ n, f (g n))
id ┴ ┴ └─────┘ ┴ └─────┘ ┴ ┴ ┴ ┴ ┴
typ ┴ ┴ └─────┘ ┴ └─────┘ ┴ ┴ ┴ ┴ ┴
46 | prec {f g} : primrec f → primrec g → primrec (unpaired (λ z n,
id ┴ ┴ └─────┘ ┴ └─────┘ ┴ └──────┘ ┴ ┴
src └──────┘
typ ┴ ┴ └─────┘ ┴ └─────┘ ┴ └──────┘ ┴ ┴
47 n.elim (f z) (λ y IH, g $ mkpair z $ mkpair y IH)))
id ┴└───┘ ┴ ┴ ┴ └┘ ┴ └────┘ ┴ └────┘ ┴ └┘
src └───┘ └────┘ └────┘
typ ┴└───┘ ┴ ┴ ┴ └┘ ┴ └────┘ ┴ └────┘ ┴ └┘
doc └────┘ └────┘
48
49 namespace primrec
50
51 theorem of_eq {f g : ℕ → ℕ} (hf : primrec f) (H : ∀ n, f n = g n) : primrec g :=
id ┴ ┴ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─────┘ ┴
src ┴ ┴ └─────┘ ┴ └─────┘
typ ┴ ┴ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─────┘ ┴
doc └─────┘ └─────┘
52 (funext H : f = g) ▸ hf
id └────┘ ┴ ┴ ┴ ┴ ┴ └┘
src └────┘ ┴ ┴
typ └────┘ ┴ ┴ ┴ ┴ ┴ └┘
53
54 theorem const : ∀ (n : ℕ), primrec (λ _, n)
id ┴ ┴ └─────┘ ┴ ┴
src ┴ └─────┘
typ ┴ ┴ └─────┘ ┴ ┴
doc └─────┘
55 | 0 := zero
id └──┘
src └──┘
typ └──┘
56 | (n+1) := succ.comp (const n)
id ┴┴ └──┘└───┘ └───┘
src ┴ └───────┘
typ ┴┴ └──┘└───┘ └───┘
57
58 protected theorem id : primrec id :=
id └─────┘ └┘
src └─────┘ └┘
typ └─────┘ └┘
doc └─────┘
59 (left.pair right).of_eq $ λ n, by simp
id └──┘└───┘ └───┘ └───┘ ┴
src └───────┘ └───┘ └───┘ └────
typ └──┘└───┘ └───┘ └───┘ ┴ └────
doc └────
txt └────
par └────
pid └
st └─────
60
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
61 theorem prec1 {f} (m : ℕ) (hf : primrec f) : primrec (λ n,
id ┴ └─────┘ ┴ └─────┘ ┴
src ┴ └─────┘ └─────┘
typ ┴ └─────┘ ┴ └─────┘ ┴
doc └─────┘ └─────┘
62 n.elim m (λ y IH, f $ mkpair y IH)) :=
id ┴└───┘ ┴ ┴ └┘ ┴ └────┘ ┴ └┘
src └───┘ └────┘
typ ┴└───┘ ┴ ┴ └┘ ┴ └────┘ ┴ └┘
doc └────┘
63 ((prec (const m) (hf.comp right)).comp
id └──┘ └───┘ ┴ └┘└───┘ └───┘ └──┘
src └──┘ └───┘ └───┘ └───┘ └──┘
typ └──┘ └───┘ ┴ └┘└───┘ └───┘ └──┘
64 (zero.pair primrec.id)).of_eq $
id └──┘└───┘ └────────┘ └───┘
src └───────┘ └────────┘ └───┘
typ └──┘└───┘ └────────┘ └───┘
65 λ n, by simp; dsimp; rw [unpair_mkpair]
id ┴
src └──┘ └───┘ └──┘ └─
typ ┴ └──┘ └───┘ └──┘ └─
doc └──┘ └───┘ └──┘ └─
txt └──┘ └───┘ └──┘ └─
par └──┘ └───┘ └──┘ └─
pid └┘ ┴└
st └────────────────┘ └
66
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
67 theorem cases1 {f} (m : ℕ) (hf : primrec f) : primrec (nat.cases m f) :=
id ┴ └─────┘ ┴ └─────┘ └───────┘ ┴ ┴
src ┴ └─────┘ └─────┘ └───────┘
typ ┴ └─────┘ ┴ └─────┘ └───────┘ ┴ ┴
doc └─────┘ └─────┘
68 (prec1 m (hf.comp left)).of_eq $ by simp [cases]
id └───┘ ┴ └┘└───┘ └──┘ └───┘ └───┘
src └───┘ └───┘ └──┘ └───┘ └────┘└───┘└─
typ └───┘ ┴ └┘└───┘ └──┘ └───┘ └────┘└───┘└─
doc └────┘ └─
txt └────┘ └─
par └────┘ └─
pid ┴┴ ┴└
st └─────────────
69
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
70 theorem cases {f g} (hf : primrec f) (hg : primrec g) :
id └─────┘ ┴ └─────┘ ┴
src └─────┘ └─────┘
typ └─────┘ ┴ └─────┘ ┴
doc └─────┘ └─────┘
71 primrec (unpaired (λ z n, n.cases (f z) (λ y, g $ mkpair z y))) :=
id └─────┘ └──────┘ ┴ ┴ ┴└────┘ ┴ ┴ ┴ ┴ └────┘ ┴ ┴
src └─────┘ └──────┘ └────┘ └────┘
typ └─────┘ └──────┘ ┴ ┴ ┴└────┘ ┴ ┴ ┴ ┴ └────┘ ┴ ┴
doc └─────┘ └────┘
72 (prec hf (hg.comp (pair left (left.comp right)))).of_eq $ by simp [cases]
id └──┘ └┘ └┘└───┘ └──┘ └──┘ └──┘└───┘ └───┘ └───┘ └───┘
src └──┘ └───┘ └──┘ └──┘ └───────┘ └───┘ └───┘ └────┘└───┘└─
typ └──┘ └┘ └┘└───┘ └──┘ └──┘ └──┘└───┘ └───┘ └───┘ └────┘└───┘└─
doc └────┘ └─
txt └────┘ └─
par └────┘ └─
pid ┴┴ ┴└
st └─────────────
73
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
74 protected theorem swap : primrec (unpaired (function.swap mkpair)) :=
id └─────┘ └──────┘ └───────────┘ └────┘
src └─────┘ └──────┘ └───────────┘ └────┘
typ └─────┘ └──────┘ └───────────┘ └────┘
doc └─────┘ └────┘
75 (pair right left).of_eq $ λ n, by simp
id └──┘ └───┘ └──┘ └───┘ ┴
src └──┘ └───┘ └──┘ └───┘ └────
typ └──┘ └───┘ └──┘ └───┘ ┴ └────
doc └────
txt └────
par └────
pid └
st └─────
76
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
77 theorem swap' {f} (hf : primrec (unpaired f)) : primrec (unpaired (function.swap f)) :=
id └─────┘ └──────┘ ┴ └─────┘ └──────┘ └───────────┘ ┴
src └─────┘ └──────┘ └─────┘ └──────┘ └───────────┘
typ └─────┘ └──────┘ ┴ └─────┘ └──────┘ └───────────┘ ┴
doc └─────┘ └─────┘
78 (hf.comp primrec.swap).of_eq $ λ n, by simp
id └┘└───┘ └──────────┘ └───┘ ┴
src └───┘ └──────────┘ └───┘ └────
typ └┘└───┘ └──────────┘ └───┘ ┴ └────
doc └────
txt └────
par └────
pid └
st └─────
79
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
80 theorem pred : primrec pred :=
id └─────┘ └──┘
src └─────┘ └──┘
typ └─────┘ └──┘
doc └─────┘
81 (cases1 0 primrec.id).of_eq $ λ n, by cases n; simp *
id └────┘ └────────┘ └───┘ ┴ ┴
src └────┘ └────────┘ └───┘ └────┘ └──────
typ └────┘ └────────┘ └───┘ ┴ └────┘┴ └──────
doc └────┘ └──────
txt └────┘ └──────
par └────┘ └──────
pid ┴ ┴┴└
st └────────────────
82
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
83 theorem add : primrec (unpaired (+)) :=
id └─────┘ └──────┘ ┴
src └─────┘ └──────┘ ┴
typ └─────┘ └──────┘ ┴
doc └─────┘
84 (prec primrec.id ((succ.comp right).comp right)).of_eq $
id └──┘ └────────┘ └──┘└───┘ └───┘ └──┘ └───┘ └───┘
src └──┘ └────────┘ └───────┘ └───┘ └──┘ └───┘ └───┘
typ └──┘ └────────┘ └──┘└───┘ └───┘ └──┘ └───┘ └───┘
85 λ p, by simp; induction p.unpair.2; simp [*, -add_comm, add_succ]
id ┴ └──────┘ └──────┘
src └──┘ └────────┘└──────┘└┘ └──────────────────┘└──────┘└─
typ ┴ └──┘ └────────┘└──────┘└┘ └──────────────────┘└──────┘└─
doc └──┘ └────────┘└──────┘└┘ └──────────────────┘ └─
txt └──┘ └────────┘ └┘ └──────────────────┘ └─
par └──┘ └────────┘ └┘ └──────────────────┘ └─
pid ┴ └┘ ┴└─────────────┘ ┴└
st └──────────────────────────────────────────────────────────
86
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
87 theorem sub : primrec (unpaired has_sub.sub) :=
id └─────┘ └──────┘ └─────────┘
src └─────┘ └──────┘ └─────────┘
typ └─────┘ └──────┘ └─────────┘
doc └─────┘
88 (prec primrec.id ((pred.comp right).comp right)).of_eq $
id └──┘ └────────┘ └──┘└───┘ └───┘ └──┘ └───┘ └───┘
src └──┘ └────────┘ └──┘└───┘ └───┘ └──┘ └───┘ └───┘
typ └──┘ └────────┘ └──┘└───┘ └───┘ └──┘ └───┘ └───┘
89 λ p, by simp; induction p.unpair.2; simp [*, -add_comm, sub_succ]
id ┴ └──────┘ └──────┘
src └──┘ └────────┘└──────┘└┘ └──────────────────┘└──────┘└─
typ ┴ └──┘ └────────┘└──────┘└┘ └──────────────────┘└──────┘└─
doc └──┘ └────────┘└──────┘└┘ └──────────────────┘ └─
txt └──┘ └────────┘ └┘ └──────────────────┘ └─
par └──┘ └────────┘ └┘ └──────────────────┘ └─
pid ┴ └┘ ┴└─────────────┘ ┴└
st └──────────────────────────────────────────────────────────
90
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
91 theorem mul : primrec (unpaired (*)) :=
id └─────┘ └──────┘ ┴
src └─────┘ └──────┘ ┴
typ └─────┘ └──────┘ ┴
doc └─────┘
92 (prec zero (add.comp (pair left (right.comp right)))).of_eq $
id └──┘ └──┘ └─┘└───┘ └──┘ └──┘ └───┘└───┘ └───┘ └───┘
src └──┘ └──┘ └─┘└───┘ └──┘ └──┘ └────────┘ └───┘ └───┘
typ └──┘ └──┘ └─┘└───┘ └──┘ └──┘ └───┘└───┘ └───┘ └───┘
93 λ p, by simp; induction p.unpair.2; simp [*, mul_succ]
id ┴ └──────┘ └──────┘
src └──┘ └────────┘└──────┘└┘ └───────┘└──────┘└─
typ ┴ └──┘ └────────┘└──────┘└┘ └───────┘└──────┘└─
doc └──┘ └────────┘└──────┘└┘ └───────┘ └─
txt └──┘ └────────┘ └┘ └───────┘ └─
par └──┘ └────────┘ └┘ └───────┘ └─
pid ┴ └┘ ┴└──┘ ┴└
st └───────────────────────────────────────────────
94
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
95 theorem pow : primrec (unpaired (^)) :=
id └─────┘ └──────┘ ┴
src └─────┘ └──────┘ ┴
typ └─────┘ └──────┘ ┴
doc └─────┘
96 (prec (const 1) (mul.comp (pair (right.comp right) left))).of_eq $
id └──┘ └───┘ └─┘└───┘ └──┘ └───┘└───┘ └───┘ └──┘ └───┘
src └──┘ └───┘ └─┘└───┘ └──┘ └────────┘ └───┘ └──┘ └───┘
typ └──┘ └───┘ └─┘└───┘ └──┘ └───┘└───┘ └───┘ └──┘ └───┘
97 λ p, by simp; induction p.unpair.2; simp [*, pow_succ]
id ┴ └──────┘ └──────┘
src └──┘ └────────┘└──────┘└┘ └───────┘└──────┘└─
typ ┴ └──┘ └────────┘└──────┘└┘ └───────┘└──────┘└─
doc └──┘ └────────┘└──────┘└┘ └───────┘ └─
txt └──┘ └────────┘ └┘ └───────┘ └─
par └──┘ └────────┘ └┘ └───────┘ └─
pid ┴ └┘ ┴└──┘ ┴└
st └───────────────────────────────────────────────
98
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
99 end primrec
100
101 end nat
102
103 section prio
104 set_option default_priority 100 -- see Note [default priority]
doc └──────────────┘
105 /-- A `primcodable` type is an `encodable` type for which
106 the encode/decode functions are primitive recursive. -/
107 class primcodable (α : Type*) extends encodable α :=
id └───┘ └───────┘ ┴
src └───────┘
typ └───┘ └───────┘ ┴
doc └───────┘
108 (prim : nat.primrec (λ n, encodable.encode (decode n)))
id └─────────┘ ┴ └──────────────┘ └────┘ ┴
src └─────────┘ └──────────────┘
typ └─────────┘ ┴ └──────────────┘ └────┘ ┴
doc └─────────┘
109 end prio
110
111 namespace primcodable
112 open nat.primrec
113
114 @[priority 10] instance of_denumerable (α) [denumerable α] : primcodable α :=
id └─────────┘ ┴ └─────────┘ ┴
src └─────────┘ └─────────┘
typ └─────────┘ ┴ └─────────┘ ┴
doc └─────────┘ └─────────┘
115 ⟨succ.of_eq $ by simp⟩
id └──┘└────┘
src └──┘└────┘ └──┘
typ └──┘└────┘ └──┘
doc └──┘
txt └──┘
par └──┘
st └───┘
116
117 def of_equiv (α) {β} [primcodable α] (e : β ≃ α) : primcodable β :=
id └─────────┘ ┴ ┴ ┴ ┴ └─────────┘ ┴
src └─────────┘ ┴ └─────────┘
typ └─────────┘ ┴ ┴ ┴ ┴ └─────────┘ ┴
doc └─────────┘ ┴ └─────────┘
118 { prim := (primcodable.prim α).of_eq $ λ n,
id └──────────────┘ ┴ └───┘ ┴
src └──────────────┘ └───┘
typ └──────────────┘ ┴ └───┘ ┴
119 show encode (decode α n) =
id └────┘ └────┘ ┴ ┴ ┴
src └────┘ └────┘ ┴
typ └────┘ └────┘ ┴ ┴ ┴
120 (option.cases_on (option.map e.symm (decode α n))
id └─────────────┘ └────────┘ ┴└───┘ └────┘ ┴ ┴
src └─────────────┘ └────────┘ └───┘ └────┘
typ └─────────────┘ └────────┘ ┴└───┘ └────┘ ┴ ┴
121 0 (λ a, nat.succ (encode (e a))) : ℕ),
id ┴ └──────┘ └────┘ ┴ ┴ ┴
src └──────┘ └────┘ ┴
typ ┴ └──────┘ └────┘ ┴ ┴ ┴
122 by cases decode α n; dsimp; simp,
id └────┘ ┴ ┴
src └────┘└────┘┴ ┴ └───┘ └──┘
typ └────┘└────┘┴┴┴┴ └───┘ └──┘
doc └────┘ ┴ ┴ └───┘ └──┘
txt └────┘ ┴ ┴ └───┘ └──┘
par └────┘ ┴ ┴ └───┘ └──┘
pid ┴ ┴ ┴
st └────────────────────────────┘
123 ..encodable.of_equiv α e }
id └────────────────┘ ┴ ┴
src └────────────────┘
typ └────────────────┘ ┴ ┴
doc └────────────────┘
124
125 instance empty : primcodable empty :=
id └─────────┘ └───┘
src └─────────┘ └───┘
typ └─────────┘ └───┘
doc └─────────┘
126 ⟨zero⟩
id └──┘
src └──┘
typ └──┘
127
128 instance unit : primcodable punit :=
id └─────────┘ └───┘
src └─────────┘ └───┘
typ └─────────┘ └───┘
doc └─────────┘
129 ⟨(cases1 1 zero).of_eq $ λ n, by cases n; simp⟩
id └────┘ └──┘ └───┘ ┴ ┴
src └────┘ └──┘ └───┘ └────┘ └──┘
typ └────┘ └──┘ └───┘ ┴ └────┘┴ └──┘
doc └────┘ └──┘
txt └────┘ └──┘
par └────┘ └──┘
pid ┴
st └────────────┘
130
131 instance option {α : Type*} [h : primcodable α] : primcodable (option α) :=
id └─────────┘ ┴ └─────────┘ └────┘ ┴
src └─────────┘ └─────────┘ └────┘
typ └─────────┘ ┴ └─────────┘ └────┘ ┴
doc └─────────┘ └─────────┘
132 ⟨(cases1 1 ((cases1 0 (succ.comp succ)).comp (primcodable.prim α))).of_eq $
id └────┘ └────┘ └──┘└───┘ └──┘ └──┘ └──────────────┘ ┴ └───┘
src └────┘ └────┘ └───────┘ └──┘ └──┘ └──────────────┘ └───┘
typ └────┘ └────┘ └──┘└───┘ └──┘ └──┘ └──────────────┘ ┴ └───┘
133 λ n, by cases n; simp; cases decode α n; refl⟩
id ┴ ┴ └────┘ ┴ ┴
src └────┘ └──┘ └────┘└────┘┴ ┴ └──┘
typ ┴ └────┘┴ └──┘ └────┘└────┘┴┴┴┴ └──┘
doc └────┘ └──┘ └────┘ ┴ ┴ └──┘
txt └────┘ └──┘ └────┘ ┴ ┴ └──┘
par └────┘ └──┘ └────┘ ┴ ┴ └──┘
pid ┴ ┴ ┴ ┴
st └────────────────────────────────────┘
134
135 instance bool : primcodable bool :=
id └─────────┘ └──┘
src └─────────┘ └──┘
typ └─────────┘ └──┘
doc └─────────┘
136 ⟨(cases1 1 (cases1 2 zero)).of_eq $
id └────┘ └────┘ └──┘ └───┘
src └────┘ └────┘ └──┘ └───┘
typ └────┘ └────┘ └──┘ └───┘
137 λ n, begin
id ┴
typ ┴
st └─────
138 cases n, {refl}, cases n, {refl},
id ┴ ┴
src └────┘ └──┘ └────┘ └──┘
typ └────┘┴ └──┘ └────┘┴ └──┘
doc └────┘ └──┘ └────┘ └──┘
txt └────┘ └──┘ └────┘ └──┘
par └────┘ └──┘ └────┘ └──┘
pid ┴ ┴
st ────────┘└─────┘└┘└──────┘└─────┘└┘└
139 rw decode_ge_two, {refl},
id └───────────┘
src └─┘└───────────┘ └──┘
typ └─┘└───────────┘ └──┘
doc └─┘ └──┘
txt └─┘ └──┘
par └─┘ └──┘
pid ┴
st ─────────────────┘└─────┘└┘└
140 exact dec_trivial
id └─────────┘
src └────┘└─────────┘┴
typ └────┘└─────────┘┴
doc └────┘└─────────┘┴
txt └────┘ ┴
par └────┘ ┴
pid ┴ ┴
st ───────────────────┘
141 end⟩
st └─┘
142
143 end primcodable
144
145 /-- `primrec f` means `f` is primitive recursive (after
146 encoding its input and output as natural numbers). -/
147 def primrec {α β} [primcodable α] [primcodable β] (f : α → β) : Prop :=
id └─────────┘ ┴ └─────────┘ ┴ ┴ ┴
src └─────────┘ └─────────┘
typ └─────────┘ ┴ └─────────┘ ┴ ┴ ┴
doc └─────────┘ └─────────┘
148 nat.primrec (λ n, encode ((decode α n).map f))
id └─────────┘ ┴ └────┘ └────┘ ┴ ┴ └─┘ ┴
src └─────────┘ └────┘ └────┘ └─┘
typ └─────────┘ ┴ └────┘ └────┘ ┴ ┴ └─┘ ┴
doc └─────────┘
149
150 namespace primrec
151 variables {α : Type*} {β : Type*} {σ : Type*}
id ┴
typ ┴
152 variables [primcodable α] [primcodable β] [primcodable σ]
id └─────────┘ └─────────┘ └─────────┘
src └─────────┘ └─────────┘ └─────────┘
typ └─────────┘ └─────────┘ └─────────┘
doc └─────────┘ └─────────┘ └─────────┘
153 open nat.primrec
154
155 protected theorem encode : primrec (@encode α _) :=
id └─────┘ └────┘ ┴
src └─────┘ └────┘
typ └─────┘ └────┘ ┴
doc └─────┘
156 (primcodable.prim α).of_eq $ λ n, by cases decode α n; refl
id └──────────────┘ ┴ └───┘ ┴ └────┘ ┴ ┴
src └──────────────┘ └───┘ └────┘└────┘┴ ┴ └────
typ └──────────────┘ ┴ └───┘ ┴ └────┘└────┘┴┴┴┴ └────
doc └────┘ ┴ ┴ └────
txt └────┘ ┴ ┴ └────
par └────┘ ┴ ┴ └────
pid ┴ ┴ ┴ └
st └───────────────────────
157
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
158 protected theorem decode : primrec (decode α) :=
id └─────┘ └────┘ ┴
src └─────┘ └────┘
typ └─────┘ └────┘ ┴
doc └─────┘
159 succ.comp (primcodable.prim α)
id └──┘└───┘ └──────────────┘ ┴
src └───────┘ └──────────────┘
typ └──┘└───┘ └──────────────┘ ┴
160
161 theorem dom_denumerable {α β} [denumerable α] [primcodable β]
id └─────────┘ ┴ └─────────┘ ┴
src └─────────┘ └─────────┘
typ └─────────┘ ┴ └─────────┘ ┴
doc └─────────┘ └─────────┘
162 {f : α → β} : primrec f ↔ nat.primrec (λ n, encode (f (of_nat α n))) :=
id ┴ ┴ └─────┘ ┴ ┴ └─────────┘ ┴ └────┘ ┴ └────┘ ┴ ┴
src └─────┘ ┴ └─────────┘ └────┘ └────┘
typ ┴ ┴ └─────┘ ┴ ┴ └─────────┘ ┴ └────┘ ┴ └────┘ ┴ ┴
doc └─────┘ └─────────┘
163 ⟨λ h, (pred.comp h).of_eq $ λ n, by simp; refl,
id ┴ └──┘└───┘ ┴ └───┘ ┴
src └──┘└───┘ └───┘ └──┘ └──┘
typ ┴ └──┘└───┘ ┴ └───┘ ┴ └──┘ └──┘
doc └──┘ └──┘
txt └──┘ └──┘
par └──┘ └──┘
st └─────────┘
164 λ h, (succ.comp h).of_eq $ λ n, by simp; refl⟩
id ┴ └──┘└───┘ ┴ └───┘ ┴
src └───────┘ └───┘ └──┘ └──┘
typ ┴ └──┘└───┘ ┴ └───┘ ┴ └──┘ └──┘
doc └──┘ └──┘
txt └──┘ └──┘
par └──┘ └──┘
st └─────────┘
165
166 theorem nat_iff {f : ℕ → ℕ} : primrec f ↔ nat.primrec f :=
id ┴ ┴ └─────┘ ┴ ┴ └─────────┘ ┴
src ┴ ┴ └─────┘ ┴ └─────────┘
typ ┴ ┴ └─────┘ ┴ ┴ └─────────┘ ┴
doc └─────┘ └─────────┘
167 dom_denumerable
id └─────────────┘
src └─────────────┘
typ └─────────────┘
168
169 theorem encdec : primrec (λ n, encode (decode α n)) :=
id └─────┘ ┴ └────┘ └────┘ ┴ ┴
src └─────┘ └────┘ └────┘
typ └─────┘ ┴ └────┘ └────┘ ┴ ┴
doc └─────┘
170 nat_iff.2 (primcodable.prim α)
id └─────┘┴ └──────────────┘ ┴
src └─────┘┴ └──────────────┘
typ └─────┘┴ └──────────────┘ ┴
171
172 theorem option_some : primrec (@some α) :=
id └─────┘ └──┘ ┴
src └─────┘ └──┘
typ └─────┘ └──┘ ┴
doc └─────┘
173 ((cases1 0 (succ.comp succ)).comp (primcodable.prim α)).of_eq $
id └────┘ └──┘└───┘ └──┘ └──┘ └──────────────┘ ┴ └───┘
src └────┘ └───────┘ └──┘ └──┘ └──────────────┘ └───┘
typ └────┘ └──┘└───┘ └──┘ └──┘ └──────────────┘ ┴ └───┘
174 λ n, by cases decode α n; simp
id ┴ └────┘ ┴ ┴
src └────┘└────┘┴ ┴ └────
typ ┴ └────┘└────┘┴┴┴┴ └────
doc └────┘ ┴ ┴ └────
txt └────┘ ┴ ┴ └────
par └────┘ ┴ ┴ └────
pid ┴ ┴ ┴ └
st └───────────────────────
175
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
176 theorem of_eq {f g : α → σ} (hf : primrec f) (H : ∀ n, f n = g n) : primrec g :=
id ┴ ┴ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─────┘ ┴
src └─────┘ ┴ └─────┘
typ ┴ ┴ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─────┘ ┴
doc └─────┘ └─────┘
177 (funext H : f = g) ▸ hf
id └────┘ ┴ ┴ ┴ ┴ ┴ └┘
src └────┘ ┴ ┴
typ └────┘ ┴ ┴ ┴ ┴ ┴ └┘
178
179 theorem const (x : σ) : primrec (λ a : α, x) :=
id ┴ └─────┘ ┴ ┴
src └─────┘
typ ┴ └─────┘ ┴ ┴
doc └─────┘
180 ((cases1 0 (const (encode x).succ)).comp (primcodable.prim α)).of_eq $
id └────┘ └───┘ └────┘ ┴ └──┘ └──┘ └──────────────┘ ┴ └───┘
src └────┘ └───┘ └────┘ └──┘ └──┘ └──────────────┘ └───┘
typ └────┘ └───┘ └────┘ ┴ └──┘ └──┘ └──────────────┘ ┴ └───┘
181 λ n, by cases decode α n; refl
id ┴ └────┘ ┴ ┴
src └────┘└────┘┴ ┴ └────
typ ┴ └────┘└────┘┴┴┴┴ └────
doc └────┘ ┴ ┴ └────
txt └────┘ ┴ ┴ └────
par └────┘ ┴ ┴ └────
pid ┴ ┴ ┴ └
st └───────────────────────
182
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
183 protected theorem id : primrec (@id α) :=
id └─────┘ └┘ ┴
src └─────┘ └┘
typ └─────┘ └┘ ┴
doc └─────┘
184 (primcodable.prim α).of_eq $ by simp
id └──────────────┘ ┴ └───┘
src └──────────────┘ └───┘ └────
typ └──────────────┘ ┴ └───┘ └────
doc └────
txt └────
par └────
pid └
st └─────
185
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
186 theorem comp {f : β → σ} {g : α → β}
id ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴
187 (hf : primrec f) (hg : primrec g) : primrec (λ a, f (g a)) :=
id └─────┘ ┴ └─────┘ ┴ └─────┘ ┴ ┴ ┴ ┴
src └─────┘ └─────┘ └─────┘
typ └─────┘ ┴ └─────┘ ┴ └─────┘ ┴ ┴ ┴ ┴
doc └─────┘ └─────┘ └─────┘
188 ((cases1 0 (hf.comp $ pred.comp hg)).comp (primcodable.prim α)).of_eq $
id └────┘ └┘└───┘ └──┘└───┘ └┘ └──┘ └──────────────┘ ┴ └───┘
src └────┘ └───┘ └──┘└───┘ └──┘ └──────────────┘ └───┘
typ └────┘ └┘└───┘ └──┘└───┘ └┘ └──┘ └──────────────┘ ┴ └───┘
189 λ n, begin
id ┴
typ ┴
st └─────
190 cases decode α n, {refl},
id └────┘ ┴ ┴
src └────┘└────┘┴ ┴ └──┘
typ └────┘└────┘┴┴┴┴ └──┘
doc └────┘ ┴ ┴ └──┘
txt └────┘ ┴ ┴ └──┘
par └────┘ ┴ ┴ └──┘
pid ┴ ┴ ┴
st ─────────────────┘└─────┘└┘└
191 simp [encodek]
id └─────┘
src └────┘└─────┘└┘
typ └────┘└─────┘└┘
doc └────┘ └┘
txt └────┘ └┘
par └────┘ └┘
pid ┴┴ ┴┴
st ────────────────┘
192 end
st └─┘
193
194 theorem succ : primrec nat.succ := nat_iff.2 nat.primrec.succ
id └─────┘ └──────┘ └─────┘┴ └──────────────┘
src └─────┘ └──────┘ └─────┘┴ └──────────────┘
typ └─────┘ └──────┘ └─────┘┴ └──────────────┘
doc └─────┘
195
196 theorem pred : primrec nat.pred := nat_iff.2 nat.primrec.pred
id └─────┘ └──────┘ └─────┘┴ └──────────────┘
src └─────┘ └──────┘ └─────┘┴ └──────────────┘
typ └─────┘ └──────┘ └─────┘┴ └──────────────┘
doc └─────┘
197
198 theorem encode_iff {f : α → σ} : primrec (λ a, encode (f a)) ↔ primrec f :=
id ┴ ┴ └─────┘ ┴ └────┘ ┴ ┴ ┴ └─────┘ ┴
src └─────┘ └────┘ ┴ └─────┘
typ ┴ ┴ └─────┘ ┴ └────┘ ┴ ┴ ┴ └─────┘ ┴
doc └─────┘ └─────┘
199 ⟨λ h, nat.primrec.of_eq h $ λ n, by cases decode α n; refl,
id ┴ └───────────────┘ ┴ ┴ └────┘ ┴ ┴
src └───────────────┘ └────┘└────┘┴ ┴ └──┘
typ ┴ └───────────────┘ ┴ ┴ └────┘└────┘┴┴┴┴ └──┘
doc └────┘ ┴ ┴ └──┘
txt └────┘ ┴ ┴ └──┘
par └────┘ ┴ ┴ └──┘
pid ┴ ┴ ┴
st └─────────────────────┘
200 primrec.encode.comp⟩
id └────────────┘└───┘
src └────────────┘└───┘
typ └────────────┘└───┘
201
202 theorem of_nat_iff {α β} [denumerable α] [primcodable β]
id └─────────┘ ┴ └─────────┘ ┴
src └─────────┘ └─────────┘
typ └─────────┘ ┴ └─────────┘ ┴
doc └─────────┘ └─────────┘
203 {f : α → β} : primrec f ↔ primrec (λ n, f (of_nat α n)) :=
id ┴ ┴ └─────┘ ┴ ┴ └─────┘ ┴ ┴ └────┘ ┴ ┴
src └─────┘ ┴ └─────┘ └────┘
typ ┴ ┴ └─────┘ ┴ ┴ └─────┘ ┴ ┴ └────┘ ┴ ┴
doc └─────┘ └─────┘
204 dom_denumerable.trans $ nat_iff.symm.trans encode_iff
id └─────────────┘└────┘ └─────┘└───┘└────┘ └────────┘
src └─────────────┘└────┘ └─────┘└───┘└────┘ └────────┘
typ └─────────────┘└────┘ └─────┘└───┘└────┘ └────────┘
205
206 protected theorem of_nat (α) [denumerable α] : primrec (of_nat α) :=
id └─────────┘ ┴ └─────┘ └────┘ ┴
src └─────────┘ └─────┘ └────┘
typ └─────────┘ ┴ └─────┘ └────┘ ┴
doc └─────────┘ └─────┘
207 of_nat_iff.1 primrec.id
id └────────┘┴ └────────┘
src └────────┘┴ └────────┘
typ └────────┘┴ └────────┘
208
209 theorem option_some_iff {f : α → σ} : primrec (λ a, some (f a)) ↔ primrec f :=
id ┴ ┴ └─────┘ ┴ └──┘ ┴ ┴ ┴ └─────┘ ┴
src └─────┘ └──┘ ┴ └─────┘
typ ┴ ┴ └─────┘ ┴ └──┘ ┴ ┴ ┴ └─────┘ ┴
doc └─────┘ └─────┘
210 ⟨λ h, encode_iff.1 $ pred.comp $ encode_iff.2 h, option_some.comp⟩
id ┴ └────────┘┴ └──┘└───┘ └────────┘┴ ┴ └─────────┘└───┘
src └────────┘┴ └──┘└───┘ └────────┘┴ └─────────┘└───┘
typ ┴ └────────┘┴ └──┘└───┘ └────────┘┴ ┴ └─────────┘└───┘
211
212 theorem of_equiv {β} {e : β ≃ α} :
id ┴ ┴ ┴
src ┴
typ ┴ ┴ ┴
doc ┴
213 by haveI := primcodable.of_equiv α e; exact
id └──────────────────┘ ┴ ┴
src └───────┘└──────────────────┘┴ ┴ └─────
typ └───────┘└──────────────────┘┴┴┴┴ └─────
doc └───────┘ ┴ ┴ └─────
txt └───────┘ ┴ ┴ └─────
par └───────┘ ┴ ┴ └─────
pid ┴└─┘ ┴ ┴ └
st └─────────────────────────────────────────
214 primrec e :=
id └─────┘ ┴
src ─┘└─────┘┴ ┴
typ ─┘└─────┘┴┴┴
doc ─┘└─────┘┴ ┴
txt ─┘ ┴ ┴
par ─┘ ┴ ┴
pid ─┘ ┴ ┴
st ───────────┘
215 (primcodable.prim α).of_eq $ λ n,
id └──────────────┘ ┴ └───┘ ┴
src └──────────────┘ └───┘
typ └──────────────┘ ┴ └───┘ ┴
216 show _ = encode (option.map e (option.map _ _)),
id ┴ └────┘ └────────┘ ┴ └────────┘
src ┴ └────┘ └────────┘ └────────┘
typ ┴ └────┘ └────────┘ ┴ └────────┘
217 by cases decode α n; simp
id └────┘ ┴ ┴
src └────┘└────┘┴ ┴ └────
typ └────┘└────┘┴┴┴┴ └────
doc └────┘ ┴ ┴ └────
txt └────┘ ┴ ┴ └────
par └────┘ ┴ ┴ └────
pid ┴ ┴ ┴ └
st └───────────────────────
218
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
219 theorem of_equiv_symm {β} {e : β ≃ α} :
id ┴ ┴ ┴
src ┴
typ ┴ ┴ ┴
doc ┴
220 by haveI := primcodable.of_equiv α e; exact
id └──────────────────┘ ┴ ┴
src └───────┘└──────────────────┘┴ ┴ └─────
typ └───────┘└──────────────────┘┴┴┴┴ └─────
doc └───────┘ ┴ ┴ └─────
txt └───────┘ ┴ ┴ └─────
par └───────┘ ┴ ┴ └─────
pid ┴└─┘ ┴ ┴ └
st └─────────────────────────────────────────
221 primrec e.symm :=
id └─────┘ └────┘
src ─┘└─────┘┴└────┘┴
typ ─┘└─────┘┴└────┘┴
doc ─┘└─────┘┴ ┴
txt ─┘ ┴ ┴
par ─┘ ┴ ┴
pid ─┘ ┴ ┴
st ────────────────┘
222 by letI := primcodable.of_equiv α e; exact
id └──────────────────┘ ┴ ┴
src └──────┘└──────────────────┘┴ ┴ └────┘
typ └──────┘└──────────────────┘┴┴┴┴ └────┘
doc └──────┘ ┴ ┴ └────┘
txt └──────┘ ┴ ┴ └────┘
par └──────┘ ┴ ┴ └────┘
pid ┴└─┘ ┴ ┴ ┴
st └────────────────────────────────────────
223 encode_iff.1
id └────────┘
src └────────┘└──
typ └────────┘└──
doc └──
txt └──
par └──
pid └──
st ─────────────
224 (show primrec (λ a, encode (e (e.symm a))), by simp [primrec.encode])
id └─────┘ └────┘ └────┘ └────────────┘
src ─┘ ┴└─────┘┴ └──┘└────┘┴ ┴ └────┘┴ └──────┘└────┘└────────────┘┴└─
typ ─┘ ┴└─────┘┴ └──┘└────┘┴ ┴ └────┘┴ └──────┘└────┘└────────────┘┴└─
doc ─┘ ┴└─────┘┴ └──┘ ┴ ┴ ┴ └──────┘└────┘ ┴└─
txt ─┘ ┴ ┴ └──┘ ┴ ┴ ┴ └──────┘└────┘ ┴└─
par ─┘ ┴ ┴ └──┘ ┴ ┴ ┴ └──────┘└────┘ ┴└─
pid ─┘ ┴ ┴ └──┘ ┴ ┴ ┴ └────────────┘ └┘└
st ───────────────────────────────────────────────┘└────────────────────┘└─
225
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
226 theorem of_equiv_iff {β} (e : β ≃ α)
id ┴ ┴ ┴
src ┴
typ ┴ ┴ ┴
doc ┴
227 {f : σ → β} :
id ┴ ┴
typ ┴ ┴
228 by haveI := primcodable.of_equiv α e; exact
id └──────────────────┘ ┴ ┴
src └───────┘└──────────────────┘┴ ┴ └─────
typ └───────┘└──────────────────┘┴┴┴┴ └─────
doc └───────┘ ┴ ┴ └─────
txt └───────┘ ┴ ┴ └─────
par └───────┘ ┴ ┴ └─────
pid ┴└─┘ ┴ ┴ └
st └─────────────────────────────────────────
229 primrec (λ a, e (f a)) ↔ primrec f :=
id ┴ ┴ └─────┘ ┴
src ─┘ ┴ └──┘ ┴ ┴ └─┘┴┴└─────┘┴ ┴
typ ─┘ ┴ └──┘┴┴ ┴ └─┘┴┴└─────┘┴┴┴
doc ─┘ ┴ └──┘ ┴ ┴ └─┘ ┴└─────┘┴ ┴
txt ─┘ ┴ └──┘ ┴ ┴ └─┘ ┴ ┴ ┴
par ─┘ ┴ └──┘ ┴ ┴ └─┘ ┴ ┴ ┴
pid ─┘ ┴ └──┘ ┴ ┴ └─┘ ┴ ┴ ┴
st ────────────────────────────────────┘
230 by letI := primcodable.of_equiv α e; exact
id └──────────────────┘ ┴ ┴
src └──────┘└──────────────────┘┴ ┴ └────┘
typ └──────┘└──────────────────┘┴┴┴┴ └────┘
doc └──────┘ ┴ ┴ └────┘
txt └──────┘ ┴ ┴ └────┘
par └──────┘ ┴ ┴ └────┘
pid ┴└─┘ ┴ ┴ ┴
st └────────────────────────────────────────
231 ⟨λ h, (of_equiv_symm.comp h).of_eq (λ a, by simp), of_equiv.comp⟩
id └────────────────┘ └───────────┘
src └──┘ └────────────────┘┴ └──────┘ └──┘ ┴└──┘└─┘└───────────┘└─
typ └──┘ └────────────────┘┴ └──────┘ └──┘ ┴└──┘└─┘└───────────┘└─
doc └──┘ ┴ └──────┘ └──┘ ┴└──┘└─┘ └─
txt └──┘ ┴ └──────┘ └──┘ ┴└──┘└─┘ └─
par └──┘ ┴ └──────┘ └──┘ ┴└──┘└─┘ └─
pid └──┘ ┴ └──────┘ └──┘ └──────┘ ┴└
st ──────────────────────────────────────────┘└───┘└─────────────────
232
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
233 theorem of_equiv_symm_iff {β} (e : β ≃ α)
id ┴ ┴ ┴
src ┴
typ ┴ ┴ ┴
doc ┴
234 {f : σ → α} :
id ┴ ┴
typ ┴ ┴
235 by haveI := primcodable.of_equiv α e; exact
id └──────────────────┘ ┴ ┴
src └───────┘└──────────────────┘┴ ┴ └─────
typ └───────┘└──────────────────┘┴┴┴┴ └─────
doc └───────┘ ┴ ┴ └─────
txt └───────┘ ┴ ┴ └─────
par └───────┘ ┴ ┴ └─────
pid ┴└─┘ ┴ ┴ └
st └─────────────────────────────────────────
236 primrec (λ a, e.symm (f a)) ↔ primrec f :=
id └────┘ ┴ └─────┘ ┴
src ─┘ ┴ └──┘└────┘┴ ┴ └─┘┴┴└─────┘┴ ┴
typ ─┘ ┴ └──┘└────┘┴ ┴ └─┘┴┴└─────┘┴┴┴
doc ─┘ ┴ └──┘ ┴ ┴ └─┘ ┴└─────┘┴ ┴
txt ─┘ ┴ └──┘ ┴ ┴ └─┘ ┴ ┴ ┴
par ─┘ ┴ └──┘ ┴ ┴ └─┘ ┴ ┴ ┴
pid ─┘ ┴ └──┘ ┴ ┴ └─┘ ┴ ┴ ┴
st ─────────────────────────────────────────┘
237 by letI := primcodable.of_equiv α e; exact
id └──────────────────┘ ┴ ┴
src └──────┘└──────────────────┘┴ ┴ └────┘
typ └──────┘└──────────────────┘┴┴┴┴ └────┘
doc └──────┘ ┴ ┴ └────┘
txt └──────┘ ┴ ┴ └────┘
par └──────┘ ┴ ┴ └────┘
pid ┴└─┘ ┴ ┴ ┴
st └────────────────────────────────────────
238 ⟨λ h, (of_equiv.comp h).of_eq (λ a, by simp), of_equiv_symm.comp⟩
id └───────────┘ └────────────────┘
src └──┘ └───────────┘┴ └──────┘ └──┘ ┴└──┘└─┘└────────────────┘└─
typ └──┘ └───────────┘┴ └──────┘ └──┘ ┴└──┘└─┘└────────────────┘└─
doc └──┘ ┴ └──────┘ └──┘ ┴└──┘└─┘ └─
txt └──┘ ┴ └──────┘ └──┘ ┴└──┘└─┘ └─
par └──┘ ┴ └──────┘ └──┘ ┴└──┘└─┘ └─
pid └──┘ ┴ └──────┘ └──┘ └──────┘ ┴└
st ─────────────────────────────────────┘└───┘└──────────────────────
239
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
240 end primrec
241
242 namespace primcodable
243 open nat.primrec
244
245 instance prod {α β} [primcodable α] [primcodable β] : primcodable (α × β) :=
id └─────────┘ ┴ └─────────┘ ┴ └─────────┘ ┴ ┴ ┴
src └─────────┘ └─────────┘ └─────────┘ ┴
typ └─────────┘ ┴ └─────────┘ ┴ └─────────┘ ┴ ┴ ┴
doc └─────────┘ └─────────┘ └─────────┘
246 ⟨((cases zero ((cases zero succ).comp
id └───┘ └──┘ └───┘ └──┘ └──┘ └──┘
src └───┘ └──┘ └───┘ └──┘ └──┘ └──┘
typ └───┘ └──┘ └───┘ └──┘ └──┘ └──┘
247 (pair right ((primcodable.prim β).comp left)))).comp
id └──┘ └───┘ └──────────────┘ ┴ └──┘ └──┘ └──┘
src └──┘ └───┘ └──────────────┘ └──┘ └──┘ └──┘
typ └──┘ └───┘ └──────────────┘ ┴ └──┘ └──┘ └──┘
248 (pair right ((primcodable.prim α).comp left))).of_eq $
id └──┘ └───┘ └──────────────┘ ┴ └──┘ └──┘ └───┘
src └──┘ └───┘ └──────────────┘ └──┘ └──┘ └───┘
typ └──┘ └───┘ └──────────────┘ ┴ └──┘ └──┘ └───┘
249 λ n, begin
id ┴
typ ┴
st └─────
250 simp [nat.unpaired],
id └──────────┘
src └────┘└──────────┘┴
typ └────┘└──────────┘┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴┴ ┴
st ────────────────────┘└─
251 cases decode α n.unpair.1, { simp },
id └────┘ ┴ └──────┘
src └────┘└────┘┴ ┴└──────┘└┘ └───┘
typ └────┘└────┘┴┴┴└──────┘└┘ └───┘
doc └────┘ ┴ ┴└──────┘└┘ └───┘
txt └────┘ ┴ ┴ └┘ └───┘
par └────┘ ┴ ┴ └┘ └───┘
pid ┴ ┴ ┴ └┘ ┴
st ──────────────────────────┘└──┘└───┘└┘└
252 cases decode β n.unpair.2; simp
id └────┘ ┴ └──────┘
src └────┘└────┘┴ ┴└──────┘└┘ └───┘
typ └────┘└────┘┴┴┴└──────┘└┘ └───┘
doc └────┘ ┴ ┴└──────┘└┘ └───┘
txt └────┘ ┴ ┴ └┘ └───┘
par └────┘ ┴ ┴ └┘ └───┘
pid ┴ ┴ ┴ └┘ ┴
st ─────────────────────────────────┘
253 end⟩
st └─┘
254
255 end primcodable
256
257 namespace primrec
258 variables {α : Type*} {σ : Type*} [primcodable α] [primcodable σ]
id └─────────┘ └─────────┘
src └─────────┘ └─────────┘
typ └─────────┘ └─────────┘
doc └─────────┘ └─────────┘
259 open nat.primrec
260
261 theorem fst {α β} [primcodable α] [primcodable β] :
id └─────────┘ ┴ └─────────┘ ┴
src └─────────┘ └─────────┘
typ └─────────┘ ┴ └─────────┘ ┴
doc └─────────┘ └─────────┘
262 primrec (@prod.fst α β) :=
id └─────┘ └──────┘ ┴ ┴
src └─────┘ └──────┘
typ └─────┘ └──────┘ ┴ ┴
doc └─────┘
263 ((cases zero ((cases zero (nat.primrec.succ.comp left)).comp
id └───┘ └──┘ └───┘ └──┘ └──────────────┘└───┘ └──┘ └──┘
src └───┘ └──┘ └───┘ └──┘ └───────────────────┘ └──┘ └──┘
typ └───┘ └──┘ └───┘ └──┘ └──────────────┘└───┘ └──┘ └──┘
264 (pair right ((primcodable.prim β).comp left)))).comp
id └──┘ └───┘ └──────────────┘ ┴ └──┘ └──┘ └──┘
src └──┘ └───┘ └──────────────┘ └──┘ └──┘ └──┘
typ └──┘ └───┘ └──────────────┘ ┴ └──┘ └──┘ └──┘
265 (pair right ((primcodable.prim α).comp left))).of_eq $
id └──┘ └───┘ └──────────────┘ ┴ └──┘ └──┘ └───┘
src └──┘ └───┘ └──────────────┘ └──┘ └──┘ └───┘
typ └──┘ └───┘ └──────────────┘ ┴ └──┘ └──┘ └───┘
266 λ n, begin
id ┴
typ ┴
st └─────
267 simp,
src └──┘
typ └──┘
doc └──┘
txt └──┘
par └──┘
st ─────┘└─
268 cases decode α n.unpair.1; simp,
id └────┘ ┴ └──────┘
src └────┘└────┘┴ ┴└──────┘└┘ └──┘
typ └────┘└────┘┴┴┴└──────┘└┘ └──┘
doc └────┘ ┴ ┴└──────┘└┘ └──┘
txt └────┘ ┴ ┴ └┘ └──┘
par └────┘ ┴ ┴ └┘ └──┘
pid ┴ ┴ ┴ └┘
st ────────────────────────────────┘└─
269 cases decode β n.unpair.2; simp
id └────┘ ┴ └──────┘
src └────┘└────┘┴ ┴└──────┘└┘ └───┘
typ └────┘└────┘┴┴┴└──────┘└┘ └───┘
doc └────┘ ┴ ┴└──────┘└┘ └───┘
txt └────┘ ┴ ┴ └┘ └───┘
par └────┘ ┴ ┴ └┘ └───┘
pid ┴ ┴ ┴ └┘ ┴
st ─────────────────────────────────┘
270 end
st └─┘
271
272 theorem snd {α β} [primcodable α] [primcodable β] :
id └─────────┘ ┴ └─────────┘ ┴
src └─────────┘ └─────────┘
typ └─────────┘ ┴ └─────────┘ ┴
doc └─────────┘ └─────────┘
273 primrec (@prod.snd α β) :=
id └─────┘ └──────┘ ┴ ┴
src └─────┘ └──────┘
typ └─────┘ └──────┘ ┴ ┴
doc └─────┘
274 ((cases zero ((cases zero (nat.primrec.succ.comp right)).comp
id └───┘ └──┘ └───┘ └──┘ └──────────────┘└───┘ └───┘ └──┘
src └───┘ └──┘ └───┘ └──┘ └───────────────────┘ └───┘ └──┘
typ └───┘ └──┘ └───┘ └──┘ └──────────────┘└───┘ └───┘ └──┘
275 (pair right ((primcodable.prim β).comp left)))).comp
id └──┘ └───┘ └──────────────┘ ┴ └──┘ └──┘ └──┘
src └──┘ └───┘ └──────────────┘ └──┘ └──┘ └──┘
typ └──┘ └───┘ └──────────────┘ ┴ └──┘ └──┘ └──┘
276 (pair right ((primcodable.prim α).comp left))).of_eq $
id └──┘ └───┘ └──────────────┘ ┴ └──┘ └──┘ └───┘
src └──┘ └───┘ └──────────────┘ └──┘ └──┘ └───┘
typ └──┘ └───┘ └──────────────┘ ┴ └──┘ └──┘ └───┘
277 λ n, begin
id ┴
typ ┴
st └─────
278 simp,
src └──┘
typ └──┘
doc └──┘
txt └──┘
par └──┘
st ─────┘└─
279 cases decode α n.unpair.1; simp,
id └────┘ ┴ └──────┘
src └────┘└────┘┴ ┴└──────┘└┘ └──┘
typ └────┘└────┘┴┴┴└──────┘└┘ └──┘
doc └────┘ ┴ ┴└──────┘└┘ └──┘
txt └────┘ ┴ ┴ └┘ └──┘
par └────┘ ┴ ┴ └┘ └──┘
pid ┴ ┴ ┴ └┘
st ────────────────────────────────┘└─
280 cases decode β n.unpair.2; simp
id └────┘ ┴ └──────┘
src └────┘└────┘┴ ┴└──────┘└┘ └───┘
typ └────┘└────┘┴┴┴└──────┘└┘ └───┘
doc └────┘ ┴ ┴└──────┘└┘ └───┘
txt └────┘ ┴ ┴ └┘ └───┘
par └────┘ ┴ ┴ └┘ └───┘
pid ┴ ┴ ┴ └┘ ┴
st ─────────────────────────────────┘
281 end
st └─┘
282
283 theorem pair {α β γ} [primcodable α] [primcodable β] [primcodable γ]
id └─────────┘ ┴ └─────────┘ ┴ └─────────┘ ┴
src └─────────┘ └─────────┘ └─────────┘
typ └─────────┘ ┴ └─────────┘ ┴ └─────────┘ ┴
doc └─────────┘ └─────────┘ └─────────┘
284 {f : α → β} {g : α → γ} (hf : primrec f) (hg : primrec g) :
id ┴ ┴ ┴ ┴ └─────┘ ┴ └─────┘ ┴
src └─────┘ └─────┘
typ ┴ ┴ ┴ ┴ └─────┘ ┴ └─────┘ ┴
doc └─────┘ └─────┘
285 primrec (λ a, (f a, g a)) :=
id └─────┘ ┴ ┴┴ ┴ ┴ ┴
src └─────┘ ┴
typ └─────┘ ┴ ┴┴ ┴ ┴ ┴
doc └─────┘
286 ((cases1 0 (nat.primrec.succ.comp $
id └────┘ └──────────────┘└───┘
src └────┘ └───────────────────┘
typ └────┘ └──────────────┘└───┘
287 pair (nat.primrec.pred.comp hf) (nat.primrec.pred.comp hg))).comp
id └──┘ └──────────────┘└───┘ └┘ └──────────────┘└───┘ └┘ └──┘
src └──┘ └──────────────┘└───┘ └──────────────┘└───┘ └──┘
typ └──┘ └──────────────┘└───┘ └┘ └──────────────┘└───┘ └┘ └──┘
288 (primcodable.prim α)).of_eq $
id └──────────────┘ ┴ └───┘
src └──────────────┘ └───┘
typ └──────────────┘ ┴ └───┘
289 λ n, by cases decode α n; simp [encodek]; refl
id ┴ └────┘ ┴ ┴ └─────┘
src └────┘└────┘┴ ┴ └────┘└─────┘┴ └────
typ ┴ └────┘└────┘┴┴┴┴ └────┘└─────┘┴ └────
doc └────┘ ┴ ┴ └────┘ ┴ └────
txt └────┘ ┴ ┴ └────┘ ┴ └────
par └────┘ ┴ ┴ └────┘ ┴ └────
pid ┴ ┴ ┴ ┴┴ ┴ └
st └───────────────────────────────────────
290
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
291 theorem unpair : primrec nat.unpair :=
id └─────┘ └────────┘
src └─────┘ └────────┘
typ └─────┘ └────────┘
doc └─────┘ └────────┘
292 (pair (nat_iff.2 nat.primrec.left) (nat_iff.2 nat.primrec.right)).of_eq $
id └──┘ └─────┘┴ └──────────────┘ └─────┘┴ └───────────────┘ └───┘
src └──┘ └─────┘┴ └──────────────┘ └─────┘┴ └───────────────┘ └───┘
typ └──┘ └─────┘┴ └──────────────┘ └─────┘┴ └───────────────┘ └───┘
293 λ n, by simp
id ┴
src └────
typ ┴ └────
doc └────
txt └────
par └────
pid └
st └─────
294
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
295 theorem list_nth₁ : ∀ (l : list α), primrec l.nth
id ┴ └──┘ ┴ └─────┘ ┴└──┘
src └──┘ └─────┘ └──┘
typ ┴ └──┘ ┴ └─────┘ ┴└──┘
doc └─────┘
296 | [] := dom_denumerable.2 zero
id └┘ └─────────────┘┴ └──┘
src └┘ └─────────────┘┴ └──┘
typ └┘ └─────────────┘┴ └──┘
297 | (a::l) := dom_denumerable.2 $
id ┴└┘┴ └─────────────┘┴
src └┘ └─────────────┘┴
typ ┴└┘┴ └─────────────┘┴
298 (cases1 (encode a).succ $ dom_denumerable.1 $ list_nth₁ l).of_eq $
id └────┘ └────┘ └──┘ └─────────────┘┴ └───────┘ └───┘
src └────┘ └────┘ └──┘ └─────────────┘┴ └───┘
typ └────┘ └────┘ └──┘ └─────────────┘┴ └───────┘ └───┘
299 λ n, by cases n; simp
id ┴ ┴
src └────┘ └────
typ ┴ └────┘┴ └────
doc └────┘ └────
txt └────┘ └────
par └────┘ └────
pid ┴ └
st └──────────────
300
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
301 end primrec
302
303 /-- `primrec₂ f` means `f` is a binary primitive recursive function.
304 This is technically unnecessary since we can always curry all
305 the arguments together, but there are enough natural two-arg
306 functions that it is convenient to express this directly. -/
307 def primrec₂ {α β σ} [primcodable α] [primcodable β] [primcodable σ] (f : α → β → σ) :=
id └─────────┘ ┴ └─────────┘ ┴ └─────────┘ ┴ ┴ ┴ ┴
src └─────────┘ └─────────┘ └─────────┘
typ └─────────┘ ┴ └─────────┘ ┴ └─────────┘ ┴ ┴ ┴ ┴
doc └─────────┘ └─────────┘ └─────────┘
308 primrec (λ p : α × β, f p.1 p.2)
id └─────┘ ┴ ┴ ┴ ┴ ┴┴ ┴┴
src └─────┘ ┴ ┴ ┴
typ └─────┘ ┴ ┴ ┴ ┴ ┴┴ ┴┴
doc └─────┘
309
310 /-- `primrec_pred p` means `p : α → Prop` is a (decidable)
311 primitive recursive predicate, which is to say that
312 `to_bool ∘ p : α → bool` is primitive recursive. -/
313 def primrec_pred {α} [primcodable α] (p : α → Prop)
id └─────────┘ ┴ ┴
src └─────────┘
typ └─────────┘ ┴ ┴
doc └─────────┘
314 [decidable_pred p] := primrec (λ a, to_bool (p a))
id └────────────┘ ┴ └─────┘ ┴ └─────┘ ┴ ┴
src └────────────┘ └─────┘ └─────┘
typ └────────────┘ ┴ └─────┘ ┴ └─────┘ ┴ ┴
doc └─────┘
315
316 /-- `primrec_rel p` means `p : α → β → Prop` is a (decidable)
317 primitive recursive relation, which is to say that
318 `to_bool ∘ p : α → β → bool` is primitive recursive. -/
319 def primrec_rel {α β} [primcodable α] [primcodable β]
id └─────────┘ ┴ └─────────┘ ┴
src └─────────┘ └─────────┘
typ └─────────┘ ┴ └─────────┘ ┴
doc └─────────┘ └─────────┘
320 (s : α → β → Prop) [∀ a b, decidable (s a b)] :=
id ┴ ┴ ┴ ┴ └───────┘ ┴ ┴ ┴
src └───────┘
typ ┴ ┴ ┴ ┴ └───────┘ ┴ ┴ ┴
321 primrec₂ (λ a b, to_bool (s a b))
id └──────┘ ┴ ┴ └─────┘ ┴ ┴ ┴
src └──────┘ └─────┘
typ └──────┘ ┴ ┴ └─────┘ ┴ ┴ ┴
doc └──────┘
322
323 namespace primrec₂
324 variables {α : Type*} {β : Type*} {σ : Type*}
id ┴
typ ┴
325 variables [primcodable α] [primcodable β] [primcodable σ]
id └─────────┘ └─────────┘ └─────────┘
src └─────────┘ └─────────┘ └─────────┘
typ └─────────┘ └─────────┘ └─────────┘
doc └─────────┘ └─────────┘ └─────────┘
326
327 theorem of_eq {f g : α → β → σ} (hg : primrec₂ f) (H : ∀ a b, f a b = g a b) : primrec₂ g :=
id ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──────┘ ┴
src └──────┘ ┴ └──────┘
typ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──────┘ ┴
doc └──────┘ └──────┘
328 (by funext a b; apply H : f = g) ▸ hg
id ┴ ┴ ┴ ┴ └┘
src └────────┘ └────┘ ┴ ┴ ┴
typ └────────┘ └────┘ ┴ ┴ ┴ ┴ ┴ └┘
doc └────────┘ └────┘ ┴
txt └────────┘ └────┘ ┴
par └────────┘ └────┘ ┴
pid └──┘ ┴ ┴
st └───────────────────┘
329
330 theorem const (x : σ) : primrec₂ (λ (a : α) (b : β), x) := primrec.const _
id ┴ └──────┘ ┴ ┴ ┴ └───────────┘
src └──────┘ └───────────┘
typ ┴ └──────┘ ┴ ┴ ┴ └───────────┘
doc └──────┘
331
332 protected theorem pair : primrec₂ (@prod.mk α β) :=
id └──────┘ └─────┘ ┴ ┴
src └──────┘ └─────┘
typ └──────┘ └─────┘ ┴ ┴
doc └──────┘
333 primrec.pair primrec.fst primrec.snd
id └──────────┘ └─────────┘ └─────────┘
src └──────────┘ └─────────┘ └─────────┘
typ └──────────┘ └─────────┘ └─────────┘
334
335 theorem left : primrec₂ (λ (a : α) (b : β), a) := primrec.fst
id └──────┘ ┴ ┴ ┴ └─────────┘
src └──────┘ └─────────┘
typ └──────┘ ┴ ┴ ┴ └─────────┘
doc └──────┘
336
337 theorem right : primrec₂ (λ (a : α) (b : β), b) := primrec.snd
id └──────┘ ┴ ┴ ┴ └─────────┘
src └──────┘ └─────────┘
typ └──────┘ ┴ ┴ ┴ └─────────┘
doc └──────┘
338
339 theorem mkpair : primrec₂ nat.mkpair :=
id └──────┘ └────────┘
src └──────┘ └────────┘
typ └──────┘ └────────┘
doc └──────┘ └────────┘
340 by simp [primrec₂, primrec]; constructor
id └──────┘ └─────┘
src └────┘└──────┘└┘└─────┘┴ └───────────
typ └────┘└──────┘└┘└─────┘┴ └───────────
doc └────┘└──────┘└┘└─────┘┴ └───────────
txt └────┘ └┘ ┴ └───────────
par └────┘ └┘ ┴ └───────────
pid ┴┴ └┘ ┴ └
st └──────────────────────────────────────
341
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
342 theorem unpaired {f : ℕ → ℕ → α} : primrec (nat.unpaired f) ↔ primrec₂ f :=
id ┴ ┴ ┴ └─────┘ └──────────┘ ┴ ┴ └──────┘ ┴
src ┴ ┴ └─────┘ └──────────┘ ┴ └──────┘
typ ┴ ┴ ┴ └─────┘ └──────────┘ ┴ ┴ └──────┘ ┴
doc └─────┘ └──────┘
343 ⟨λ h, by simpa using h.comp mkpair,
id ┴ └────┘ └────┘
src └──────────┘└────┘┴└────┘
typ ┴ └──────────┘└────┘┴└────┘
doc └──────────┘ ┴
txt └──────────┘ ┴
par └──────────┘ ┴
pid ┴└────┘ ┴
st └────────────────────────┘
344 λ h, h.comp primrec.unpair⟩
id ┴ ┴└───┘ └────────────┘
src └───┘ └────────────┘
typ ┴ ┴└───┘ └────────────┘
345
346 theorem unpaired' {f : ℕ → ℕ → ℕ} : nat.primrec (nat.unpaired f) ↔ primrec₂ f :=
id ┴ ┴ ┴ └─────────┘ └──────────┘ ┴ ┴ └──────┘ ┴
src ┴ ┴ ┴ └─────────┘ └──────────┘ ┴ └──────┘
typ ┴ ┴ ┴ └─────────┘ └──────────┘ ┴ ┴ └──────┘ ┴
doc └─────────┘ └──────┘
347 primrec.nat_iff.symm.trans unpaired
id └─────────────┘└───┘└────┘ └──────┘
src └─────────────┘└───┘└────┘ └──────┘
typ └─────────────┘└───┘└────┘ └──────┘
348
349 theorem encode_iff {f : α → β → σ} : primrec₂ (λ a b, encode (f a b)) ↔ primrec₂ f :=
id ┴ ┴ ┴ └──────┘ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ └──────┘ ┴
src └──────┘ └────┘ ┴ └──────┘
typ ┴ ┴ ┴ └──────┘ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ └──────┘ ┴
doc └──────┘ └──────┘
350 primrec.encode_iff
id └────────────────┘
src └────────────────┘
typ └────────────────┘
351
352 theorem option_some_iff {f : α → β → σ} : primrec₂ (λ a b, some (f a b)) ↔ primrec₂ f :=
id ┴ ┴ ┴ └──────┘ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ └──────┘ ┴
src └──────┘ └──┘ ┴ └──────┘
typ ┴ ┴ ┴ └──────┘ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ └──────┘ ┴
doc └──────┘ └──────┘
353 primrec.option_some_iff
id └─────────────────────┘
src └─────────────────────┘
typ └─────────────────────┘
354
355 theorem of_nat_iff {α β σ}
356 [denumerable α] [denumerable β] [primcodable σ]
id └─────────┘ ┴ └─────────┘ ┴ └─────────┘ ┴
src └─────────┘ └─────────┘ └─────────┘
typ └─────────┘ ┴ └─────────┘ ┴ └─────────┘ ┴
doc └─────────┘ └─────────┘ └─────────┘
357 {f : α → β → σ} : primrec₂ f ↔ primrec₂ (λ m n : ℕ,
id ┴ ┴ ┴ └──────┘ ┴ ┴ └──────┘ ┴
src └──────┘ ┴ └──────┘ ┴
typ ┴ ┴ ┴ └──────┘ ┴ ┴ └──────┘ ┴
doc └──────┘ └──────┘
358 f (of_nat α m) (of_nat β n)) :=
id ┴ └────┘ ┴ ┴ └────┘ ┴ ┴
src └────┘ └────┘
typ ┴ └────┘ ┴ ┴ └────┘ ┴ ┴
359 (primrec.of_nat_iff.trans $ by simp).trans unpaired
id └────────────────┘└────┘ └───┘ └──────┘
src └────────────────┘└────┘ └──┘ └───┘ └──────┘
typ └────────────────┘└────┘ └──┘ └───┘ └──────┘
doc └──┘
txt └──┘
par └──┘
st └───┘
360
361 theorem uncurry {f : α → β → σ} : primrec (function.uncurry f) ↔ primrec₂ f :=
id ┴ ┴ ┴ └─────┘ └──────────────┘ ┴ ┴ └──────┘ ┴
src └─────┘ └──────────────┘ ┴ └──────┘
typ ┴ ┴ ┴ └─────┘ └──────────────┘ ┴ ┴ └──────┘ ┴
doc └─────┘ └──────┘
362 by rw [show function.uncurry f = λ (p : α × β), f p.1 p.2,
id └──────────────┘ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴└──────────────┘┴ ┴┴┴ └────┘ ┴┴┴ └─┘ ┴ └─┘ └───
typ └──┘ ┴└──────────────┘┴ ┴┴┴ └────┘┴┴┴┴┴└─┘┴┴ └─┘ └───
doc └──┘ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ └─┘ ┴ └─┘ └───
txt └──┘ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ └─┘ ┴ └─┘ └───
par └──┘ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ └─┘ ┴ └─┘ └───
pid └┘ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ └─┘ ┴ └─┘ └───
st └────────────────────────────────────────────────────────
363 from funext $ λ ⟨a, b⟩, rfl]; refl
id └────┘ └─┘
src ───────────┘└────┘┴ ┴ └┘ └┘ └─┘└─┘┴ └────
typ ───────────┘└────┘┴ ┴ └┘ └┘ └─┘└─┘┴ └────
doc ───────────┘ ┴ ┴ └┘ └┘ └─┘ ┴ └────
txt ───────────┘ ┴ ┴ └┘ └┘ └─┘ ┴ └────
par ───────────┘ ┴ ┴ └┘ └┘ └─┘ ┴ └────
pid ───────────┘ ┴ ┴ └┘ └┘ └─┘ ┴ └
st ─────────────────────────────────┘┴└──────
364
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
365 theorem curry {f : α × β → σ} : primrec₂ (function.curry f) ↔ primrec f :=
id ┴ ┴ ┴ ┴ └──────┘ └────────────┘ ┴ ┴ └─────┘ ┴
src ┴ └──────┘ └────────────┘ ┴ └─────┘
typ ┴ ┴ ┴ ┴ └──────┘ └────────────┘ ┴ ┴ └─────┘ ┴
doc └──────┘ └─────┘
366 by rw [← uncurry, function.uncurry_curry]
id └─────┘ └────────────────────┘
src └────┘└─────┘└┘└────────────────────┘└─
typ └────┘└─────┘└┘└────────────────────┘└─
doc └────┘ └┘ └─
txt └────┘ └┘ └─
par └────┘ └┘ └─
pid └──┘ └┘ ┴└
st └────────────┘└──────────────────────┘┴└
367
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
368 end primrec₂
369
370 section comp
371 variables {α : Type*} {β : Type*} {γ : Type*} {δ : Type*} {σ : Type*}
372 variables [primcodable α] [primcodable β] [primcodable γ] [primcodable δ] [primcodable σ]
id └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘
src └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘
typ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘
doc └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘
373
374 theorem primrec.comp₂ {f : γ → σ} {g : α → β → γ}
id ┴ ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴ ┴
375 (hf : primrec f) (hg : primrec₂ g) :
id └─────┘ ┴ └──────┘ ┴
src └─────┘ └──────┘
typ └─────┘ ┴ └──────┘ ┴
doc └─────┘ └──────┘
376 primrec₂ (λ a b, f (g a b)) := hf.comp hg
id └──────┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘└───┘ └┘
src └──────┘ └───┘
typ └──────┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘└───┘ └┘
doc └──────┘
377
378 theorem primrec₂.comp
379 {f : β → γ → σ} {g : α → β} {h : α → γ}
id ┴ ┴ ┴ ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴
380 (hf : primrec₂ f) (hg : primrec g) (hh : primrec h) :
id └──────┘ ┴ └─────┘ ┴ └─────┘ ┴
src └──────┘ └─────┘ └─────┘
typ └──────┘ ┴ └─────┘ ┴ └─────┘ ┴
doc └──────┘ └─────┘ └─────┘
381 primrec (λ a, f (g a) (h a)) := hf.comp (hg.pair hh)
id └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘└───┘ └┘└───┘ └┘
src └─────┘ └───┘ └───┘
typ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘└───┘ └┘└───┘ └┘
doc └─────┘
382
383 theorem primrec₂.comp₂
384 {f : γ → δ → σ} {g : α → β → γ} {h : α → β → δ}
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
385 (hf : primrec₂ f) (hg : primrec₂ g) (hh : primrec₂ h) :
id └──────┘ ┴ └──────┘ ┴ └──────┘ ┴
src └──────┘ └──────┘ └──────┘
typ └──────┘ ┴ └──────┘ ┴ └──────┘ ┴
doc └──────┘ └──────┘ └──────┘
386 primrec₂ (λ a b, f (g a b) (h a b)) := hf.comp hg hh
id └──────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘└───┘ └┘ └┘
src └──────┘ └───┘
typ └──────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘└───┘ └┘ └┘
doc └──────┘
387
388 theorem primrec_pred.comp
389 {p : β → Prop} [decidable_pred p] {f : α → β} :
id ┴ └────────────┘ ┴ ┴ ┴
src └────────────┘
typ ┴ └────────────┘ ┴ ┴ ┴
390 primrec_pred p → primrec f →
id └──────────┘ ┴ └─────┘ ┴
src └──────────┘ └─────┘
typ └──────────┘ ┴ └─────┘ ┴
doc └──────────┘ └─────┘
391 primrec_pred (λ a, p (f a)) := primrec.comp
id └──────────┘ ┴ ┴ ┴ ┴ └──────────┘
src └──────────┘ └──────────┘
typ └──────────┘ ┴ ┴ ┴ ┴ └──────────┘
doc └──────────┘
392
393 theorem primrec_rel.comp
394 {R : β → γ → Prop} [∀ a b, decidable (R a b)] {f : α → β} {g : α → γ} :
id ┴ ┴ ┴ ┴ └───────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └───────┘
typ ┴ ┴ ┴ ┴ └───────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴
395 primrec_rel R → primrec f → primrec g →
id └─────────┘ ┴ └─────┘ ┴ └─────┘ ┴
src └─────────┘ └─────┘ └─────┘
typ └─────────┘ ┴ └─────┘ ┴ └─────┘ ┴
doc └─────────┘ └─────┘ └─────┘
396 primrec_pred (λ a, R (f a) (g a)) := primrec₂.comp
id └──────────┘ ┴ ┴ ┴ ┴ ┴ ┴ └───────────┘
src └──────────┘ └───────────┘
typ └──────────┘ ┴ ┴ ┴ ┴ ┴ ┴ └───────────┘
doc └──────────┘
397
398 theorem primrec_rel.comp₂
399 {R : γ → δ → Prop} [∀ a b, decidable (R a b)] {f : α → β → γ} {g : α → β → δ} :
id ┴ ┴ ┴ ┴ └───────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └───────┘
typ ┴ ┴ ┴ ┴ └───────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
400 primrec_rel R → primrec₂ f → primrec₂ g →
id └─────────┘ ┴ └──────┘ ┴ └──────┘ ┴
src └─────────┘ └──────┘ └──────┘
typ └─────────┘ ┴ └──────┘ ┴ └──────┘ ┴
doc └─────────┘ └──────┘ └──────┘
401 primrec_rel (λ a b, R (f a b) (g a b)) := primrec_rel.comp
id └─────────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──────────────┘
src └─────────┘ └──────────────┘
typ └─────────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──────────────┘
doc └─────────┘
402
403 end comp
404
405 theorem primrec_pred.of_eq {α} [primcodable α]
id └─────────┘ ┴
src └─────────┘
typ └─────────┘ ┴
doc └─────────┘
406 {p q : α → Prop} [decidable_pred p] [decidable_pred q]
id ┴ └────────────┘ ┴ └────────────┘ ┴
src └────────────┘ └────────────┘
typ ┴ └────────────┘ ┴ └────────────┘ ┴
407 (hp : primrec_pred p) (H : ∀ a, p a ↔ q a) : primrec_pred q :=
id └──────────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──────────┘ ┴
src └──────────┘ ┴ └──────────┘
typ └──────────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──────────┘ ┴
doc └──────────┘ └──────────┘
408 primrec.of_eq hp (λ a, to_bool_congr (H a))
id └───────────┘ └┘ ┴ └───────────┘ ┴ ┴
src └───────────┘ └───────────┘
typ └───────────┘ └┘ ┴ └───────────┘ ┴ ┴
409
410 theorem primrec_rel.of_eq {α β} [primcodable α] [primcodable β]
id └─────────┘ ┴ └─────────┘ ┴
src └─────────┘ └─────────┘
typ └─────────┘ ┴ └─────────┘ ┴
doc └─────────┘ └─────────┘
411 {r s : α → β → Prop} [∀ a b, decidable (r a b)] [∀ a b, decidable (s a b)]
id ┴ ┴ ┴ ┴ └───────┘ ┴ ┴ ┴ ┴ ┴ └───────┘ ┴ ┴ ┴
src └───────┘ └───────┘
typ ┴ ┴ ┴ ┴ └───────┘ ┴ ┴ ┴ ┴ ┴ └───────┘ ┴ ┴ ┴
412 (hr : primrec_rel r) (H : ∀ a b, r a b ↔ s a b) : primrec_rel s :=
id └─────────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─────────┘ ┴
src └─────────┘ ┴ └─────────┘
typ └─────────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─────────┘ ┴
doc └─────────┘ └─────────┘
413 primrec₂.of_eq hr (λ a b, to_bool_congr (H a b))
id └────────────┘ └┘ ┴ ┴ └───────────┘ ┴ ┴ ┴
src └────────────┘ └───────────┘
typ └────────────┘ └┘ ┴ ┴ └───────────┘ ┴ ┴ ┴
414
415 namespace primrec₂
416 variables {α : Type*} {β : Type*} {σ : Type*}
417 variables [primcodable α] [primcodable β] [primcodable σ]
id └─────────┘ └─────────┘ └─────────┘
src └─────────┘ └─────────┘ └─────────┘
typ └─────────┘ └─────────┘ └─────────┘
doc └─────────┘ └─────────┘ └─────────┘
418 open nat.primrec
419
420 theorem swap {f : α → β → σ} (h : primrec₂ f) : primrec₂ (function.swap f) :=
id ┴ ┴ ┴ └──────┘ ┴ └──────┘ └───────────┘ ┴
src └──────┘ └──────┘ └───────────┘
typ ┴ ┴ ┴ └──────┘ ┴ └──────┘ └───────────┘ ┴
doc └──────┘ └──────┘
421 h.comp₂ primrec₂.right primrec₂.left
id ┴└────┘ └────────────┘ └───────────┘
src └────┘ └────────────┘ └───────────┘
typ ┴└────┘ └────────────┘ └───────────┘
422
423 theorem nat_iff {f : α → β → σ} : primrec₂ f ↔
id ┴ ┴ ┴ └──────┘ ┴ ┴
src └──────┘ ┴
typ ┴ ┴ ┴ └──────┘ ┴ ┴
doc └──────┘
424 nat.primrec (nat.unpaired $ λ m n : ℕ,
id └─────────┘ └──────────┘ ┴
src └─────────┘ └──────────┘ ┴
typ └─────────┘ └──────────┘ ┴
doc └─────────┘
425 encode $ (decode α m).bind $ λ a, (decode β n).map (f a)) :=
id └────┘ └────┘ ┴ ┴ └──┘ ┴ └────┘ ┴ ┴ └─┘ ┴ ┴
src └────┘ └────┘ └──┘ └────┘ └─┘
typ └────┘ └────┘ ┴ ┴ └──┘ ┴ └────┘ ┴ ┴ └─┘ ┴ ┴
426 have ∀ (a : option α) (b : option β),
id └────┘ ┴ └────┘ ┴
src └────┘ └────┘
typ └────┘ ┴ └────┘ ┴
427 option.map (λ (p : α × β), f p.1 p.2)
id └────────┘ ┴ ┴ ┴ ┴ ┴┴ ┴┴
src └────────┘ ┴ ┴ ┴
typ └────────┘ ┴ ┴ ┴ ┴ ┴┴ ┴┴
428 (option.bind a (λ (a : α), option.map (prod.mk a) b)) =
id └─────────┘ ┴ ┴ └────────┘ └─────┘ ┴ ┴ ┴
src └─────────┘ └────────┘ └─────┘ ┴
typ └─────────┘ ┴ ┴ └────────┘ └─────┘ ┴ ┴ ┴
429 option.bind a (λ a, option.map (f a) b),
id └─────────┘ ┴ ┴ └────────┘ ┴ ┴ ┴
src └─────────┘ └────────┘
typ └─────────┘ ┴ ┴ └────────┘ ┴ ┴ ┴
430 by intros; cases a; [refl, {cases b; refl}],
id ┴ ┴ ┴
src └────┘ └────┘ ┴└──┘ └────┘ └──┘
typ └────┘ └────┘┴ ┴└──┘ └────┘┴ └──┘
doc └────┘ └────┘ └──┘ └────┘ └──┘
txt └────┘ └────┘ └──┘ └────┘ └──┘
par └────┘ └────┘ └──┘ └────┘ └──┘
pid ┴ ┴
st └───────────────────────┘└────────────┘└┘
431 by simp [primrec₂, primrec, this]
id └──────┘ └─────┘ └──┘
src └────┘└──────┘└┘└─────┘└┘ └─
typ └────┘└──────┘└┘└─────┘└┘└──┘└─
doc └────┘└──────┘└┘└─────┘└┘ └─
txt └────┘ └┘ └┘ └─
par └────┘ └┘ └┘ └─
pid ┴┴ └┘ └┘ ┴└
st └───────────────────────────────
432
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
433 theorem nat_iff' {f : α → β → σ} : primrec₂ f ↔ primrec₂ (λ m n : ℕ,
id ┴ ┴ ┴ └──────┘ ┴ ┴ └──────┘ ┴
src └──────┘ ┴ └──────┘ ┴
typ ┴ ┴ ┴ └──────┘ ┴ ┴ └──────┘ ┴
doc └──────┘ └──────┘
434 option.bind (decode α m) (λ a, option.map (f a) (decode β n))) :=
id └─────────┘ └────┘ ┴ ┴ ┴ └────────┘ ┴ ┴ └────┘ ┴ ┴
src └─────────┘ └────┘ └────────┘ └────┘
typ └─────────┘ └────┘ ┴ ┴ ┴ └────────┘ ┴ ┴ └────┘ ┴ ┴
435 nat_iff.trans $ unpaired'.trans encode_iff
id └─────┘└────┘ └───────┘└────┘ └────────┘
src └─────┘└────┘ └───────┘└────┘ └────────┘
typ └─────┘└────┘ └───────┘└────┘ └────────┘
436
437 end primrec₂
438
439 namespace primrec
440 variables {α : Type*} {β : Type*} {γ : Type*} {δ : Type*} {σ : Type*}
441 variables [primcodable α] [primcodable β] [primcodable γ] [primcodable δ] [primcodable σ]
id └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘
src └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘
typ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘
doc └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘
442
443 theorem to₂ {f : α × β → σ} (hf : primrec f) : primrec₂ (λ a b, f (a, b)) :=
id ┴ ┴ ┴ ┴ └─────┘ ┴ └──────┘ ┴ ┴ ┴ ┴┴ ┴
src ┴ └─────┘ └──────┘ ┴
typ ┴ ┴ ┴ ┴ └─────┘ ┴ └──────┘ ┴ ┴ ┴ ┴┴ ┴
doc └─────┘ └──────┘
444 hf.of_eq $ λ ⟨a, b⟩, rfl
id └┘└────┘ ┴ └─┘
src └────┘ └─┘
typ └┘└────┘ ┴ └─┘
445
446 theorem nat_elim {f : α → β} {g : α → ℕ × β → β}
id ┴ ┴ ┴ ┴ ┴ ┴ ┴
src ┴ ┴
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴
447 (hf : primrec f) (hg : primrec₂ g) :
id └─────┘ ┴ └──────┘ ┴
src └─────┘ └──────┘
typ └─────┘ ┴ └──────┘ ┴
doc └─────┘ └──────┘
448 primrec₂ (λ a (n : ℕ), n.elim (f a) (λ n IH, g a (n, IH))) :=
id └──────┘ ┴ ┴ ┴└───┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴┴ └┘
src └──────┘ ┴ └───┘ ┴
typ └──────┘ ┴ ┴ ┴└───┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴┴ └┘
doc └──────┘
449 primrec₂.nat_iff.2 $ ((nat.primrec.cases nat.primrec.zero $
id └──────────────┘┴ └───────────────┘ └──────────────┘
src └──────────────┘┴ └───────────────┘ └──────────────┘
typ └──────────────┘┴ └───────────────┘ └──────────────┘
450 (nat.primrec.prec hf $ nat.primrec.comp hg $ nat.primrec.left.pair $
id └──────────────┘ └┘ └──────────────┘ └┘ └──────────────┘└───┘
src └──────────────┘ └──────────────┘ └───────────────────┘
typ └──────────────┘ └┘ └──────────────┘ └┘ └──────────────┘└───┘
451 (nat.primrec.left.comp nat.primrec.right).pair $
id └──────────────┘└───┘ └───────────────┘ └──┘
src └───────────────────┘ └───────────────┘ └──┘
typ └──────────────┘└───┘ └───────────────┘ └──┘
452 nat.primrec.pred.comp $ nat.primrec.right.comp nat.primrec.right).comp $
id └──────────────┘└───┘ └───────────────┘└───┘ └───────────────┘ └──┘
src └──────────────┘└───┘ └────────────────────┘ └───────────────┘ └──┘
typ └──────────────┘└───┘ └───────────────┘└───┘ └───────────────┘ └──┘
453 nat.primrec.right.pair $
id └───────────────┘└───┘
src └────────────────────┘
typ └───────────────┘└───┘
454 nat.primrec.right.comp nat.primrec.left).comp $
id └───────────────┘└───┘ └──────────────┘ └──┘
src └────────────────────┘ └──────────────┘ └──┘
typ └───────────────┘└───┘ └──────────────┘ └──┘
455 nat.primrec.id.pair $ (primcodable.prim α).comp nat.primrec.left).of_eq $
id └────────────┘└───┘ └──────────────┘ ┴ └──┘ └──────────────┘ └───┘
src └────────────┘└───┘ └──────────────┘ └──┘ └──────────────┘ └───┘
typ └────────────┘└───┘ └──────────────┘ ┴ └──┘ └──────────────┘ └───┘
456 λ n, begin
id ┴
typ ┴
st └─────
457 simp,
src └──┘
typ └──┘
doc └──┘
txt └──┘
par └──┘
st ─────┘└─
458 cases decode α n.unpair.1 with a, {refl},
id └────┘ ┴ └──────┘
src └────┘└────┘┴ ┴└──────┘└───────┘ └──┘
typ └────┘└────┘┴┴┴└──────┘└───────┘ └──┘
doc └────┘ ┴ ┴└──────┘└───────┘ └──┘
txt └────┘ ┴ ┴ └───────┘ └──┘
par └────┘ ┴ ┴ └───────┘ └──┘
pid ┴ ┴ ┴ └───────┘
st ─────────────────────────────────┘└─────┘└┘└
459 simp [encodek],
id └─────┘
src └────┘└─────┘┴
typ └────┘└─────┘┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴┴ ┴
st ───────────────┘└─
460 induction n.unpair.2 with m; simp [encodek],
id └──────┘ └─────┘
src └────────┘└──────┘└───────┘ └────┘└─────┘┴
typ └────────┘└──────┘└───────┘ └────┘└─────┘┴
doc └────────┘└──────┘└───────┘ └────┘ ┴
txt └────────┘ └───────┘ └────┘ ┴
par └────────┘ └───────┘ └────┘ ┴
pid ┴ └─┘└────┘ ┴┴ ┴
st ────────────────────────────────────────────┘└─
461 simp [ih, encodek]
id └┘ └─────┘
src └────┘ └┘└─────┘└┘
typ └────┘└┘└┘└─────┘└┘
doc └────┘ └┘ └┘
txt └────┘ └┘ └┘
par └────┘ └┘ └┘
pid ┴┴ └┘ ┴┴
st ────────────────────┘
462 end
st └─┘
463
464 theorem nat_elim' {f : α → ℕ} {g : α → β} {h : α → ℕ × β → β}
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src ┴ ┴ ┴
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
465 (hf : primrec f) (hg : primrec g) (hh : primrec₂ h) :
id └─────┘ ┴ └─────┘ ┴ └──────┘ ┴
src └─────┘ └─────┘ └──────┘
typ └─────┘ ┴ └─────┘ ┴ └──────┘ ┴
doc └─────┘ └─────┘ └──────┘
466 primrec (λ a, (f a).elim (g a) (λ n IH, h a (n, IH))) :=
id └─────┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴┴ └┘
src └─────┘ └──┘ ┴
typ └─────┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴┴ └┘
doc └─────┘
467 (nat_elim hg hh).comp primrec.id hf
id └──────┘ └┘ └┘ └──┘ └────────┘ └┘
src └──────┘ └──┘ └────────┘
typ └──────┘ └┘ └┘ └──┘ └────────┘ └┘
468
469 theorem nat_elim₁ {f : ℕ → α → α} (a : α) (hf : primrec₂ f) :
id ┴ ┴ ┴ ┴ └──────┘ ┴
src ┴ └──────┘
typ ┴ ┴ ┴ ┴ └──────┘ ┴
doc └──────┘
470 primrec (nat.elim a f) :=
id └─────┘ └──────┘ ┴ ┴
src └─────┘ └──────┘
typ └─────┘ └──────┘ ┴ ┴
doc └─────┘
471 nat_elim' primrec.id (const a) $ comp₂ hf primrec₂.right
id └───────┘ └────────┘ └───┘ ┴ └───┘ └┘ └────────────┘
src └───────┘ └────────┘ └───┘ └───┘ └────────────┘
typ └───────┘ └────────┘ └───┘ ┴ └───┘ └┘ └────────────┘
472
473 theorem nat_cases' {f : α → β} {g : α → ℕ → β}
id ┴ ┴ ┴ ┴ ┴
src ┴
typ ┴ ┴ ┴ ┴ ┴
474 (hf : primrec f) (hg : primrec₂ g) :
id └─────┘ ┴ └──────┘ ┴
src └─────┘ └──────┘
typ └─────┘ ┴ └──────┘ ┴
doc └─────┘ └──────┘
475 primrec₂ (λ a, nat.cases (f a) (g a)) :=
id └──────┘ ┴ └───────┘ ┴ ┴ ┴ ┴
src └──────┘ └───────┘
typ └──────┘ ┴ └───────┘ ┴ ┴ ┴ ┴
doc └──────┘
476 nat_elim hf $ hg.comp₂ primrec₂.left $
id └──────┘ └┘ └┘└────┘ └───────────┘
src └──────┘ └────┘ └───────────┘
typ └──────┘ └┘ └┘└────┘ └───────────┘
477 comp₂ fst primrec₂.right
id └───┘ └─┘ └────────────┘
src └───┘ └─┘ └────────────┘
typ └───┘ └─┘ └────────────┘
478
479 theorem nat_cases {f : α → ℕ} {g : α → β} {h : α → ℕ → β}
id ┴ ┴ ┴ ┴ ┴ ┴ ┴
src ┴ ┴
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴
480 (hf : primrec f) (hg : primrec g) (hh : primrec₂ h) :
id └─────┘ ┴ └─────┘ ┴ └──────┘ ┴
src └─────┘ └─────┘ └──────┘
typ └─────┘ ┴ └─────┘ ┴ └──────┘ ┴
doc └─────┘ └─────┘ └──────┘
481 primrec (λ a, (f a).cases (g a) (h a)) :=
id └─────┘ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ ┴
src └─────┘ └───┘
typ └─────┘ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ ┴
doc └─────┘
482 (nat_cases' hg hh).comp primrec.id hf
id └────────┘ └┘ └┘ └──┘ └────────┘ └┘
src └────────┘ └──┘ └────────┘
typ └────────┘ └┘ └┘ └──┘ └────────┘ └┘
483
484 theorem nat_cases₁ {f : ℕ → α} (a : α) (hf : primrec f) :
id ┴ ┴ ┴ └─────┘ ┴
src ┴ └─────┘
typ ┴ ┴ ┴ └─────┘ ┴
doc └─────┘
485 primrec (nat.cases a f) :=
id └─────┘ └───────┘ ┴ ┴
src └─────┘ └───────┘
typ └─────┘ └───────┘ ┴ ┴
doc └─────┘
486 nat_cases primrec.id (const a) (comp₂ hf primrec₂.right)
id └───────┘ └────────┘ └───┘ ┴ └───┘ └┘ └────────────┘
src └───────┘ └────────┘ └───┘ └───┘ └────────────┘
typ └───────┘ └────────┘ └───┘ ┴ └───┘ └┘ └────────────┘
487
488 theorem nat_iterate {f : α → ℕ} {g : α → β} {h : α → β → β}
id ┴ ┴ ┴ ┴ ┴ ┴ ┴
src ┴
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴
489 (hf : primrec f) (hg : primrec g) (hh : primrec₂ h) :
id └─────┘ ┴ └─────┘ ┴ └──────┘ ┴
src └─────┘ └─────┘ └──────┘
typ └─────┘ ┴ └─────┘ ┴ └──────┘ ┴
doc └─────┘ └─────┘ └──────┘
490 primrec (λ a, (h a)^[f a] (g a)) :=
id └─────┘ ┴ ┴ ┴ └┘┴ ┴┴ ┴ ┴
src └─────┘ └┘ ┴
typ └─────┘ ┴ ┴ ┴ └┘┴ ┴┴ ┴ ┴
doc └─────┘
491 (nat_elim' hf hg (hh.comp₂ primrec₂.left $ snd.comp₂ primrec₂.right)).of_eq $
id └───────┘ └┘ └┘ └┘└────┘ └───────────┘ └─┘└────┘ └────────────┘ └───┘
src └───────┘ └────┘ └───────────┘ └─┘└────┘ └────────────┘ └───┘
typ └───────┘ └┘ └┘ └┘└────┘ └───────────┘ └─┘└────┘ └────────────┘ └───┘
492 λ a, by induction f a; simp [*, -nat.iterate_succ, nat.iterate_succ']
id ┴ ┴ ┴ └───────────────┘
src └────────┘ ┴ └──────────────────────────┘└───────────────┘└─
typ ┴ └────────┘┴┴┴ └──────────────────────────┘└───────────────┘└─
doc └────────┘ ┴ └──────────────────────────┘ └─
txt └────────┘ ┴ └──────────────────────────┘ └─
par └────────┘ ┴ └──────────────────────────┘ └─
pid ┴ ┴ ┴└─────────────────────┘ ┴└
st └──────────────────────────────────────────────────────────────
493
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
494 theorem option_cases {o : α → option β} {f : α → σ} {g : α → β → σ}
id ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴
src └────┘
typ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴
495 (ho : primrec o) (hf : primrec f) (hg : primrec₂ g) :
id └─────┘ ┴ └─────┘ ┴ └──────┘ ┴
src └─────┘ └─────┘ └──────┘
typ └─────┘ ┴ └─────┘ ┴ └──────┘ ┴
doc └─────┘ └─────┘ └──────┘
496 @primrec _ σ _ _ (λ a, option.cases_on (o a) (f a) (g a)) :=
id └─────┘ ┴ ┴ └─────────────┘ ┴ ┴ ┴ ┴ ┴ ┴
src └─────┘ └─────────────┘
typ └─────┘ ┴ ┴ └─────────────┘ ┴ ┴ ┴ ┴ ┴ ┴
doc └─────┘
497 encode_iff.1 $
id └────────┘┴
src └────────┘┴
typ └────────┘┴
498 (nat_cases (encode_iff.2 ho) (encode_iff.2 hf) $
id └───────┘ └────────┘┴ └┘ └────────┘┴ └┘
src └───────┘ └────────┘┴ └────────┘┴
typ └───────┘ └────────┘┴ └┘ └────────┘┴ └┘
499 pred.comp₂ $ primrec₂.encode_iff.2 $
id └──┘└────┘ └─────────────────┘┴
src └──┘└────┘ └─────────────────┘┴
typ └──┘└────┘ └─────────────────┘┴
500 (primrec₂.nat_iff'.1 hg).comp₂
id └───────────────┘┴ └┘ └───┘
src └───────────────┘┴ └───┘
typ └───────────────┘┴ └┘ └───┘
501 ((@primrec.encode α _).comp fst).to₂
id └────────────┘ ┴ └──┘ └─┘ └─┘
src └────────────┘ └──┘ └─┘ └─┘
typ └────────────┘ ┴ └──┘ └─┘ └─┘
502 primrec₂.right).of_eq $
id └────────────┘ └───┘
src └────────────┘ └───┘
typ └────────────┘ └───┘
503 λ a, by cases o a with b; simp [encodek]; refl
id ┴ ┴ ┴ └─────┘
src └────┘ ┴ └─────┘ └────┘└─────┘┴ └────
typ ┴ └────┘┴┴┴└─────┘ └────┘└─────┘┴ └────
doc └────┘ ┴ └─────┘ └────┘ ┴ └────
txt └────┘ ┴ └─────┘ └────┘ ┴ └────
par └────┘ ┴ └─────┘ └────┘ ┴ └────
pid ┴ ┴ └─────┘ ┴┴ ┴ └
st └───────────────────────────────────────
504
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
505 theorem option_bind {f : α → option β} {g : α → β → option σ}
id ┴ └────┘ ┴ ┴ ┴ └────┘ ┴
src └────┘ └────┘
typ ┴ └────┘ ┴ ┴ ┴ └────┘ ┴
506 (hf : primrec f) (hg : primrec₂ g) :
id └─────┘ ┴ └──────┘ ┴
src └─────┘ └──────┘
typ └─────┘ ┴ └──────┘ ┴
doc └─────┘ └──────┘
507 primrec (λ a, (f a).bind (g a)) :=
id └─────┘ ┴ ┴ ┴ └──┘ ┴ ┴
src └─────┘ └──┘
typ └─────┘ ┴ ┴ ┴ └──┘ ┴ ┴
doc └─────┘
508 (option_cases hf (const none) hg).of_eq $
id └──────────┘ └┘ └───┘ └──┘ └┘ └───┘
src └──────────┘ └───┘ └──┘ └───┘
typ └──────────┘ └┘ └───┘ └──┘ └┘ └───┘
509 λ a, by cases f a; refl
id ┴ ┴ ┴
src └────┘ ┴ └────
typ ┴ └────┘┴┴┴ └────
doc └────┘ ┴ └────
txt └────┘ ┴ └────
par └────┘ ┴ └────
pid ┴ ┴ └
st └────────────────
510
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
511 theorem option_bind₁ {f : α → option σ} (hf : primrec f) :
id ┴ └────┘ ┴ └─────┘ ┴
src └────┘ └─────┘
typ ┴ └────┘ ┴ └─────┘ ┴
doc └─────┘
512 primrec (λ o, option.bind o f) :=
id └─────┘ ┴ └─────────┘ ┴ ┴
src └─────┘ └─────────┘
typ └─────┘ ┴ └─────────┘ ┴ ┴
doc └─────┘
513 option_bind primrec.id (hf.comp snd).to₂
id └─────────┘ └────────┘ └┘└───┘ └─┘ └─┘
src └─────────┘ └────────┘ └───┘ └─┘ └─┘
typ └─────────┘ └────────┘ └┘└───┘ └─┘ └─┘
514
515 theorem option_map {f : α → option β} {g : α → β → σ}
id ┴ └────┘ ┴ ┴ ┴ ┴
src └────┘
typ ┴ └────┘ ┴ ┴ ┴ ┴
516 (hf : primrec f) (hg : primrec₂ g) : primrec (λ a, (f a).map (g a)) :=
id └─────┘ ┴ └──────┘ ┴ └─────┘ ┴ ┴ ┴ └─┘ ┴ ┴
src └─────┘ └──────┘ └─────┘ └─┘
typ └─────┘ ┴ └──────┘ ┴ └─────┘ ┴ ┴ ┴ └─┘ ┴ ┴
doc └─────┘ └──────┘ └─────┘
517 option_bind hf (option_some.comp₂ hg)
id └─────────┘ └┘ └─────────┘└────┘ └┘
src └─────────┘ └─────────┘└────┘
typ └─────────┘ └┘ └─────────┘└────┘ └┘
518
519 theorem option_map₁ {f : α → σ} (hf : primrec f) : primrec (option.map f) :=
id ┴ ┴ └─────┘ ┴ └─────┘ └────────┘ ┴
src └─────┘ └─────┘ └────────┘
typ ┴ ┴ └─────┘ ┴ └─────┘ └────────┘ ┴
doc └─────┘ └─────┘
520 option_map primrec.id (hf.comp snd).to₂
id └────────┘ └────────┘ └┘└───┘ └─┘ └─┘
src └────────┘ └────────┘ └───┘ └─┘ └─┘
typ └────────┘ └────────┘ └┘└───┘ └─┘ └─┘
521
522 theorem option_iget [inhabited α] : primrec (@option.iget α _) :=
id └───────┘ ┴ └─────┘ └─────────┘ ┴
src └───────┘ └─────┘ └─────────┘
typ └───────┘ ┴ └─────┘ └─────────┘ ┴
doc └─────┘ └─────────┘
523 (option_cases primrec.id (const $ default α) primrec₂.right).of_eq $
id └──────────┘ └────────┘ └───┘ └─────┘ ┴ └────────────┘ └───┘
src └──────────┘ └────────┘ └───┘ └─────┘ └────────────┘ └───┘
typ └──────────┘ └────────┘ └───┘ └─────┘ ┴ └────────────┘ └───┘
524 λ o, by cases o; refl
id ┴ ┴
src └────┘ └────
typ ┴ └────┘┴ └────
doc └────┘ └────
txt └────┘ └────
par └────┘ └────
pid ┴ └
st └──────────────
525
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
526 theorem option_is_some : primrec (@option.is_some α) :=
id └─────┘ └────────────┘ ┴
src └─────┘ └────────────┘
typ └─────┘ └────────────┘ ┴
doc └─────┘
527 (option_cases primrec.id (const ff) (const tt).to₂).of_eq $
id └──────────┘ └────────┘ └───┘ └┘ └───┘ └┘ └─┘ └───┘
src └──────────┘ └────────┘ └───┘ └┘ └───┘ └┘ └─┘ └───┘
typ └──────────┘ └────────┘ └───┘ └┘ └───┘ └┘ └─┘ └───┘
528 λ o, by cases o; refl
id ┴ ┴
src └────┘ └────
typ ┴ └────┘┴ └────
doc └────┘ └────
txt └────┘ └────
par └────┘ └────
pid ┴ └
st └──────────────
529
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
530 theorem bind_decode_iff {f : α → β → option σ} : primrec₂ (λ a n,
id ┴ ┴ └────┘ ┴ └──────┘ ┴ ┴
src └────┘ └──────┘
typ ┴ ┴ └────┘ ┴ └──────┘ ┴ ┴
doc └──────┘
531 (decode β n).bind (f a)) ↔ primrec₂ f :=
id └────┘ ┴ ┴ └──┘ ┴ ┴ ┴ └──────┘ ┴
src └────┘ └──┘ ┴ └──────┘
typ └────┘ ┴ ┴ └──┘ ┴ ┴ ┴ └──────┘ ┴
doc └──────┘
532 ⟨λ h, by simpa [encodek] using
id ┴ └─────┘
src └─────┘└─────┘└───────
typ ┴ └─────┘└─────┘└───────
doc └─────┘ └───────
txt └─────┘ └───────
par └─────┘ └───────
pid ┴┴ ┴┴└─────
st └──────────────────────
533 h.comp fst ((@primrec.encode β _).comp snd),
id └────┘ └─┘ └────────────┘ ┴ └─┘
src ──┘└────┘┴└─┘┴ └────────────┘┴ └───────┘└─┘┴
typ ──┘└────┘┴└─┘┴ └────────────┘┴┴└───────┘└─┘┴
doc ──┘ ┴ ┴ ┴ └───────┘ ┴
txt ──┘ ┴ ┴ ┴ └───────┘ ┴
par ──┘ ┴ ┴ ┴ └───────┘ ┴
pid ──┘ ┴ ┴ ┴ └───────┘ ┴
st ─────────────────────────────────────────────┘
534 λ h, option_bind (primrec.decode.comp snd) $
id ┴ └─────────┘ └────────────┘└───┘ └─┘
src └─────────┘ └────────────┘└───┘ └─┘
typ ┴ └─────────┘ └────────────┘└───┘ └─┘
535 h.comp (fst.comp fst) snd⟩
id ┴└───┘ └─┘└───┘ └─┘ └─┘
src └───┘ └─┘└───┘ └─┘ └─┘
typ ┴└───┘ └─┘└───┘ └─┘ └─┘
536
537 theorem map_decode_iff {f : α → β → σ} : primrec₂ (λ a n,
id ┴ ┴ ┴ └──────┘ ┴ ┴
src └──────┘
typ ┴ ┴ ┴ └──────┘ ┴ ┴
doc └──────┘
538 (decode β n).map (f a)) ↔ primrec₂ f :=
id └────┘ ┴ ┴ └─┘ ┴ ┴ ┴ └──────┘ ┴
src └────┘ └─┘ ┴ └──────┘
typ └────┘ ┴ ┴ └─┘ ┴ ┴ ┴ └──────┘ ┴
doc └──────┘
539 bind_decode_iff.trans primrec₂.option_some_iff
id └─────────────┘└────┘ └──────────────────────┘
src └─────────────┘└────┘ └──────────────────────┘
typ └─────────────┘└────┘ └──────────────────────┘
540
541 theorem nat_add : primrec₂ ((+) : ℕ → ℕ → ℕ) :=
id └──────┘ ┴ ┴ ┴ ┴
src └──────┘ ┴ ┴ ┴ ┴
typ └──────┘ ┴ ┴ ┴ ┴
doc └──────┘
542 primrec₂.unpaired'.1 nat.primrec.add
id └────────────────┘┴ └─────────────┘
src └────────────────┘┴ └─────────────┘
typ └────────────────┘┴ └─────────────┘
543
544 theorem nat_sub : primrec₂ (has_sub.sub : ℕ → ℕ → ℕ) :=
id └──────┘ └─────────┘ ┴ ┴ ┴
src └──────┘ └─────────┘ ┴ ┴ ┴
typ └──────┘ └─────────┘ ┴ ┴ ┴
doc └──────┘
545 primrec₂.unpaired'.1 nat.primrec.sub
id └────────────────┘┴ └─────────────┘
src └────────────────┘┴ └─────────────┘
typ └────────────────┘┴ └─────────────┘
546
547 theorem nat_mul : primrec₂ ((*) : ℕ → ℕ → ℕ) :=
id └──────┘ ┴ ┴ ┴ ┴
src └──────┘ ┴ ┴ ┴ ┴
typ └──────┘ ┴ ┴ ┴ ┴
doc └──────┘
548 primrec₂.unpaired'.1 nat.primrec.mul
id └────────────────┘┴ └─────────────┘
src └────────────────┘┴ └─────────────┘
typ └────────────────┘┴ └─────────────┘
549
550 theorem cond {c : α → bool} {f : α → σ} {g : α → σ}
id ┴ └──┘ ┴ ┴ ┴ ┴
src └──┘
typ ┴ └──┘ ┴ ┴ ┴ ┴
551 (hc : primrec c) (hf : primrec f) (hg : primrec g) :
id └─────┘ ┴ └─────┘ ┴ └─────┘ ┴
src └─────┘ └─────┘ └─────┘
typ └─────┘ ┴ └─────┘ ┴ └─────┘ ┴
doc └─────┘ └─────┘ └─────┘
552 primrec (λ a, cond (c a) (f a) (g a)) :=
id └─────┘ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴
src └─────┘ └──┘
typ └─────┘ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴
doc └─────┘
553 (nat_cases (encode_iff.2 hc) hg (hf.comp fst).to₂).of_eq $
id └───────┘ └────────┘┴ └┘ └┘ └┘└───┘ └─┘ └─┘ └───┘
src └───────┘ └────────┘┴ └───┘ └─┘ └─┘ └───┘
typ └───────┘ └────────┘┴ └┘ └┘ └┘└───┘ └─┘ └─┘ └───┘
554 λ a, by cases c a; refl
id ┴ ┴ ┴
src └────┘ ┴ └────
typ ┴ └────┘┴┴┴ └────
doc └────┘ ┴ └────
txt └────┘ ┴ └────
par └────┘ ┴ └────
pid ┴ ┴ └
st └────────────────
555
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
556 theorem ite {c : α → Prop} [decidable_pred c] {f : α → σ} {g : α → σ}
id ┴ └────────────┘ ┴ ┴ ┴ ┴ ┴
src └────────────┘
typ ┴ └────────────┘ ┴ ┴ ┴ ┴ ┴
557 (hc : primrec_pred c) (hf : primrec f) (hg : primrec g) :
id └──────────┘ ┴ └─────┘ ┴ └─────┘ ┴
src └──────────┘ └─────┘ └─────┘
typ └──────────┘ ┴ └─────┘ ┴ └─────┘ ┴
doc └──────────┘ └─────┘ └─────┘
558 primrec (λ a, if c a then f a else g a) :=
id └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └─────┘
typ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └─────┘
559 by simpa using cond hc hf hg
id └──┘ └┘ └┘ └┘
src └──────────┘└──┘┴ ┴ ┴ └
typ └──────────┘└──┘┴└┘┴└┘┴└┘└
doc └──────────┘ ┴ ┴ ┴ └
txt └──────────┘ ┴ ┴ ┴ └
par └──────────┘ ┴ ┴ ┴ └
pid ┴└────┘ ┴ ┴ ┴ └
st └──────────────────────────
560
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
561 theorem nat_le : primrec_rel ((≤) : ℕ → ℕ → Prop) :=
id └─────────┘ ┴ ┴ ┴
src └─────────┘ ┴ ┴ ┴
typ └─────────┘ ┴ ┴ ┴
doc └─────────┘
562 (nat_cases nat_sub (const tt) (const ff).to₂).of_eq $
id └───────┘ └─────┘ └───┘ └┘ └───┘ └┘ └─┘ └───┘
src └───────┘ └─────┘ └───┘ └┘ └───┘ └┘ └─┘ └───┘
typ └───────┘ └─────┘ └───┘ └┘ └───┘ └┘ └─┘ └───┘
563 λ p, begin
id ┴
typ ┴
st └─────
564 dsimp [function.swap],
id └───────────┘
src └─────┘└───────────┘┴
typ └─────┘└───────────┘┴
doc └─────┘ ┴
txt └─────┘ ┴
par └─────┘ ┴
pid ┴┴ ┴
st ──────────────────────┘└─
565 cases e : p.1 - p.2 with n,
id ┴ ┴
src └────┘ └─┘ └─┘┴┴ └───────┘
typ └────┘ └─┘ └─┘┴┴┴└───────┘
doc └────┘ └─┘ └─┘ ┴ └───────┘
txt └────┘ └─┘ └─┘ ┴ └───────┘
par └────┘ └─┘ └─┘ ┴ └───────┘
pid ┴ └─┘ └─┘ ┴ └───────┘
st ───────────────────────────┘└─
566 { simp [nat.sub_eq_zero_iff_le.1 e] },
id └────────────────────┘ ┴
src └────┘└────────────────────┘└─┘ └┘
typ └────┘└────────────────────┘└─┘┴└┘
doc └────┘ └─┘ └┘
txt └────┘ └─┘ └┘
par └────┘ └─┘ └┘
pid ┴┴ └─┘ ┴┴
st ───┘└────────────────────────────────┘└┘└
567 { simp [not_le.2 (nat.lt_of_sub_eq_succ e)] }
id └────┘ └───────────────────┘ ┴
src └────┘└────┘└─┘ └───────────────────┘┴ └─┘
typ └────┘└────┘└─┘ └───────────────────┘┴┴└─┘
doc └────┘ └─┘ ┴ └─┘
txt └────┘ └─┘ ┴ └─┘
par └────┘ └─┘ ┴ └─┘
pid ┴┴ └─┘ ┴ └┘┴
st ─────────────────────────────────────────────┘└─
568 end
st ──┘
569
570 theorem nat_min : primrec₂ (@min ℕ _) := ite nat_le fst snd
id └──────┘ └─┘ ┴ └─┘ └────┘ └─┘ └─┘
src └──────┘ └─┘ ┴ └─┘ └────┘ └─┘ └─┘
typ └──────┘ └─┘ ┴ └─┘ └────┘ └─┘ └─┘
doc └──────┘
571 theorem nat_max : primrec₂ (@max ℕ _) := ite nat_le snd fst
id └──────┘ └─┘ ┴ └─┘ └────┘ └─┘ └─┘
src └──────┘ └─┘ ┴ └─┘ └────┘ └─┘ └─┘
typ └──────┘ └─┘ ┴ └─┘ └────┘ └─┘ └─┘
doc └──────┘
572
573 theorem dom_bool (f : bool → α) : primrec f :=
id └──┘ ┴ └─────┘ ┴
src └──┘ └─────┘
typ └──┘ ┴ └─────┘ ┴
doc └─────┘
574 (cond primrec.id (const (f tt)) (const (f ff))).of_eq $
id └──┘ └────────┘ └───┘ ┴ └┘ └───┘ ┴ └┘ └───┘
src └──┘ └────────┘ └───┘ └┘ └───┘ └┘ └───┘
typ └──┘ └────────┘ └───┘ ┴ └┘ └───┘ ┴ └┘ └───┘
575 λ b, by cases b; refl
id ┴ ┴
src └────┘ └────
typ ┴ └────┘┴ └────
doc └────┘ └────
txt └────┘ └────
par └────┘ └────
pid ┴ └
st └──────────────
576
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
577 theorem dom_bool₂ (f : bool → bool → α) : primrec₂ f :=
id └──┘ └──┘ ┴ └──────┘ ┴
src └──┘ └──┘ └──────┘
typ └──┘ └──┘ ┴ └──────┘ ┴
doc └──────┘
578 (cond fst
id └──┘ └─┘
src └──┘ └─┘
typ └──┘ └─┘
579 ((dom_bool (f tt)).comp snd)
id └──────┘ ┴ └┘ └──┘ └─┘
src └──────┘ └┘ └──┘ └─┘
typ └──────┘ ┴ └┘ └──┘ └─┘
580 ((dom_bool (f ff)).comp snd)).of_eq $
id └──────┘ ┴ └┘ └──┘ └─┘ └───┘
src └──────┘ └┘ └──┘ └─┘ └───┘
typ └──────┘ ┴ └┘ └──┘ └─┘ └───┘
581 λ ⟨a, b⟩, by cases a; refl
id ┴ ┴
src └────┘ └────
typ ┴ └────┘┴ └────
doc └────┘ └────
txt └────┘ └────
par └────┘ └────
pid ┴ └
st └──────────────
582
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
583 protected theorem bnot : primrec bnot := dom_bool _
id └─────┘ └──┘ └──────┘
src └─────┘ └──┘ └──────┘
typ └─────┘ └──┘ └──────┘
doc └─────┘
584 protected theorem band : primrec₂ band := dom_bool₂ _
id └──────┘ └──┘ └───────┘
src └──────┘ └──┘ └───────┘
typ └──────┘ └──┘ └───────┘
doc └──────┘
585 protected theorem bor : primrec₂ bor := dom_bool₂ _
id └──────┘ └─┘ └───────┘
src └──────┘ └─┘ └───────┘
typ └──────┘ └─┘ └───────┘
doc └──────┘
586
587 protected theorem not {p : α → Prop} [decidable_pred p]
id ┴ └────────────┘ ┴
src └────────────┘
typ ┴ └────────────┘ ┴
588 (hp : primrec_pred p) : primrec_pred (λ a, ¬ p a) :=
id └──────────┘ ┴ └──────────┘ ┴ ┴ ┴ ┴
src └──────────┘ └──────────┘ ┴
typ └──────────┘ ┴ └──────────┘ ┴ ┴ ┴ ┴
doc └──────────┘ └──────────┘
589 (primrec.bnot.comp hp).of_eq $ λ n, by simp
id └──────────┘└───┘ └┘ └───┘ ┴
src └──────────┘└───┘ └───┘ └────
typ └──────────┘└───┘ └┘ └───┘ ┴ └────
doc └────
txt └────
par └────
pid └
st └─────
590
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
591 protected theorem and {p q : α → Prop}
id ┴
typ ┴
592 [decidable_pred p] [decidable_pred q]
id └────────────┘ ┴ └────────────┘ ┴
src └────────────┘ └────────────┘
typ └────────────┘ ┴ └────────────┘ ┴
593 (hp : primrec_pred p) (hq : primrec_pred q) :
id └──────────┘ ┴ └──────────┘ ┴
src └──────────┘ └──────────┘
typ └──────────┘ ┴ └──────────┘ ┴
doc └──────────┘ └──────────┘
594 primrec_pred (λ a, p a ∧ q a) :=
id └──────────┘ ┴ ┴ ┴ ┴ ┴ ┴
src └──────────┘ ┴
typ └──────────┘ ┴ ┴ ┴ ┴ ┴ ┴
doc └──────────┘
595 (primrec.band.comp hp hq).of_eq $ λ n, by simp
id └──────────┘└───┘ └┘ └┘ └───┘ ┴
src └──────────┘└───┘ └───┘ └────
typ └──────────┘└───┘ └┘ └┘ └───┘ ┴ └────
doc └────
txt └────
par └────
pid └
st └─────
596
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
597 protected theorem or {p q : α → Prop}
id ┴
typ ┴
598 [decidable_pred p] [decidable_pred q]
id └────────────┘ ┴ └────────────┘ ┴
src └────────────┘ └────────────┘
typ └────────────┘ ┴ └────────────┘ ┴
599 (hp : primrec_pred p) (hq : primrec_pred q) :
id └──────────┘ ┴ └──────────┘ ┴
src └──────────┘ └──────────┘
typ └──────────┘ ┴ └──────────┘ ┴
doc └──────────┘ └──────────┘
600 primrec_pred (λ a, p a ∨ q a) :=
id └──────────┘ ┴ ┴ ┴ ┴ ┴ ┴
src └──────────┘ ┴
typ └──────────┘ ┴ ┴ ┴ ┴ ┴ ┴
doc └──────────┘
601 (primrec.bor.comp hp hq).of_eq $ λ n, by simp
id └─────────┘└───┘ └┘ └┘ └───┘ ┴
src └─────────┘└───┘ └───┘ └────
typ └─────────┘└───┘ └┘ └┘ └───┘ ┴ └────
doc └────
txt └────
par └────
pid └
st └─────
602
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
603 protected theorem eq [decidable_eq α] : primrec_rel (@eq α) :=
id └──────────┘ ┴ └─────────┘ └┘ ┴
src └──────────┘ └─────────┘ └┘
typ └──────────┘ ┴ └─────────┘ └┘ ┴
doc └─────────┘
604 have primrec_rel (λ a b : ℕ, a = b), from
id └─────────┘ ┴ ┴ ┴ ┴
src └─────────┘ ┴ ┴
typ └─────────┘ ┴ ┴ ┴ ┴
doc └─────────┘
605 (primrec.and nat_le nat_le.swap).of_eq $
id └─────────┘ └────┘ └────┘└───┘ └───┘
src └─────────┘ └────┘ └────┘└───┘ └───┘
typ └─────────┘ └────┘ └────┘└───┘ └───┘
606 λ a, by simp [le_antisymm_iff],
id ┴ └─────────────┘
src └────┘└─────────────┘┴
typ ┴ └────┘└─────────────┘┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴┴ ┴
st └─────────────────────┘
607 (this.comp₂
id └──┘└────┘
src └────┘
typ └──┘└────┘
608 (primrec.encode.comp₂ primrec₂.left)
id └────────────┘└────┘ └───────────┘
src └────────────┘└────┘ └───────────┘
typ └────────────┘└────┘ └───────────┘
609 (primrec.encode.comp₂ primrec₂.right)).of_eq $
id └────────────┘└────┘ └────────────┘ └───┘
src └────────────┘└────┘ └────────────┘ └───┘
typ └────────────┘└────┘ └────────────┘ └───┘
610 λ a b, encode_injective.eq_iff
id ┴ ┴ └──────────────┘└─────┘
src └──────────────┘└─────┘
typ ┴ ┴ └──────────────┘└─────┘
611
612 theorem nat_lt : primrec_rel ((<) : ℕ → ℕ → Prop) :=
id └─────────┘ ┴ ┴ ┴
src └─────────┘ ┴ ┴ ┴
typ └─────────┘ ┴ ┴ ┴
doc └─────────┘
613 (nat_le.comp snd fst).not.of_eq $ λ p, by simp
id └────┘└───┘ └─┘ └─┘ └─┘ └───┘ ┴
src └────┘└───┘ └─┘ └─┘ └─┘ └───┘ └────
typ └────┘└───┘ └─┘ └─┘ └─┘ └───┘ ┴ └────
doc └────
txt └────
par └────
pid └
st └─────
614
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
615 theorem option_guard {p : α → β → Prop}
id ┴ ┴
typ ┴ ┴
616 [∀ a b, decidable (p a b)] (hp : primrec_rel p)
id ┴ ┴ └───────┘ ┴ ┴ ┴ └─────────┘ ┴
src └───────┘ └─────────┘
typ ┴ ┴ └───────┘ ┴ ┴ ┴ └─────────┘ ┴
doc └─────────┘
617 {f : α → β} (hf : primrec f) :
id ┴ ┴ └─────┘ ┴
src └─────┘
typ ┴ ┴ └─────┘ ┴
doc └─────┘
618 primrec (λ a, option.guard (p a) (f a)) :=
id └─────┘ ┴ └──────────┘ ┴ ┴ ┴ ┴
src └─────┘ └──────────┘
typ └─────┘ ┴ └──────────┘ ┴ ┴ ┴ ┴
doc └─────┘ └──────────┘
619 ite (hp.comp primrec.id hf) (option_some_iff.2 hf) (const none)
id └─┘ └┘└───┘ └────────┘ └┘ └─────────────┘┴ └┘ └───┘ └──┘
src └─┘ └───┘ └────────┘ └─────────────┘┴ └───┘ └──┘
typ └─┘ └┘└───┘ └────────┘ └┘ └─────────────┘┴ └┘ └───┘ └──┘
620
621 theorem option_orelse :
622 primrec₂ ((<|>) : option α → option α → option α) :=
id └──────┘ ┴ └────┘ ┴ └────┘ ┴ └────┘ ┴
src └──────┘ ┴ └────┘ └────┘ └────┘
typ └──────┘ ┴ └────┘ ┴ └────┘ ┴ └────┘ ┴
doc └──────┘
623 (option_cases fst snd (fst.comp fst).to₂).of_eq $
id └──────────┘ └─┘ └─┘ └─┘└───┘ └─┘ └─┘ └───┘
src └──────────┘ └─┘ └─┘ └─┘└───┘ └─┘ └─┘ └───┘
typ └──────────┘ └─┘ └─┘ └─┘└───┘ └─┘ └─┘ └───┘
624 λ ⟨o₁, o₂⟩, by cases o₁; cases o₂; refl
id ┴ └┘ └┘
src └────┘ └────┘ └────
typ ┴ └────┘└┘ └────┘└┘ └────
doc └────┘ └────┘ └────
txt └────┘ └────┘ └────
par └────┘ └────┘ └────
pid ┴ ┴ └
st └─────────────────────────
625
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
626 protected theorem decode2 : primrec (decode2 α) :=
id └─────┘ └─────┘ ┴
src └─────┘ └─────┘
typ └─────┘ └─────┘ ┴
doc └─────┘
627 option_bind primrec.decode $
id └─────────┘ └────────────┘
src └─────────┘ └────────────┘
typ └─────────┘ └────────────┘
628 option_guard ((@primrec.eq _ _ nat.decidable_eq).comp
id └──────────┘ └────────┘ └──────────────┘ └──┘
src └──────────┘ └────────┘ └──────────────┘ └──┘
typ └──────────┘ └────────┘ └──────────────┘ └──┘
629 (encode_iff.2 snd) (fst.comp fst)) snd
id └────────┘┴ └─┘ └─┘└───┘ └─┘ └─┘
src └────────┘┴ └─┘ └─┘└───┘ └─┘ └─┘
typ └────────┘┴ └─┘ └─┘└───┘ └─┘ └─┘
630
631 theorem list_find_index₁ {p : α → β → Prop}
id ┴ ┴
typ ┴ ┴
632 [∀ a b, decidable (p a b)] (hp : primrec_rel p) :
id ┴ ┴ └───────┘ ┴ ┴ ┴ └─────────┘ ┴
src └───────┘ └─────────┘
typ ┴ ┴ └───────┘ ┴ ┴ ┴ └─────────┘ ┴
doc └─────────┘
633 ∀ (l : list β), primrec (λ a, l.find_index (p a))
id ┴ └──┘ ┴ └─────┘ ┴ ┴└─────────┘ ┴ ┴
src └──┘ └─────┘ └─────────┘
typ ┴ └──┘ ┴ └─────┘ ┴ ┴└─────────┘ ┴ ┴
doc └─────┘
634 | [] := const 0
id └┘ └───┘
src └┘ └───┘
typ └┘ └───┘
635 | (a::l) := ite (hp.comp primrec.id (const a)) (const 0)
id ┴└┘┴ └─┘ └┘└───┘ └────────┘ └───┘ └───┘
src └┘ └─┘ └───┘ └────────┘ └───┘ └───┘
typ ┴└┘┴ └─┘ └┘└───┘ └────────┘ └───┘ └───┘
636 (succ.comp (list_find_index₁ l))
id └──┘└───┘ └──────────────┘
src └──┘└───┘
typ └──┘└───┘ └──────────────┘
637
638 theorem list_index_of₁ [decidable_eq α] (l : list α) :
id └──────────┘ ┴ └──┘ ┴
src └──────────┘ └──┘
typ └──────────┘ ┴ └──┘ ┴
639 primrec (λ a, l.index_of a) := list_find_index₁ primrec.eq l
id └─────┘ ┴ ┴└───────┘ ┴ └──────────────┘ └────────┘ ┴
src └─────┘ └───────┘ └──────────────┘ └────────┘
typ └─────┘ ┴ ┴└───────┘ ┴ └──────────────┘ └────────┘ ┴
doc └─────┘
640
641 theorem dom_fintype [fintype α] (f : α → σ) : primrec f :=
id └─────┘ ┴ ┴ ┴ └─────┘ ┴
src └─────┘ └─────┘
typ └─────┘ ┴ ┴ ┴ └─────┘ ┴
doc └─────┘ └─────┘
642 let ⟨l, nd, m⟩ := fintype.exists_univ_list α in
id └─┘ └──────────────────────┘ ┴
src └──────────────────────┘
typ └─┘ └──────────────────────┘ ┴
643 option_some_iff.1 $ begin
id └─────────────┘┴
src └─────────────┘┴
typ └─────────────┘┴
st └─────
644 haveI := decidable_eq_of_encodable α,
id └───────────────────────┘ ┴
src └───────┘└───────────────────────┘┴
typ └───────┘└───────────────────────┘┴┴
doc └───────┘ ┴
txt └───────┘ ┴
par └───────┘ ┴
pid ┴└─┘ ┴
st ─────────────────────────────────────┘└─
645 refine ((list_nth₁ (l.map f)).comp (list_index_of₁ l)).of_eq (λ a, _),
id └───────┘ └───┘ ┴ └────────────┘ ┴
src └─────┘ └───────┘┴ └───┘┴ └──────┘ └────────────┘┴ └───────┘ └────┘
typ └─────┘ └───────┘┴ └───┘┴┴└──────┘ └────────────┘┴┴└───────┘ └────┘
doc └─────┘ ┴ ┴ └──────┘ ┴ └───────┘ └────┘
txt └─────┘ ┴ ┴ └──────┘ ┴ └───────┘ └────┘
par └─────┘ ┴ ┴ └──────┘ ┴ └───────┘ └────┘
pid ┴ ┴ ┴ └──────┘ ┴ └───────┘ └────┘
st ──────────────────────────────────────────────────────────────────────┘└─
646 rw [list.nth_map, list.nth_le_nth (list.index_of_lt_length.2 (m _)),
id └──────────┘ └─────────────┘ └─────────────────────┘ ┴
src └──┘└──────────┘└┘└─────────────┘┴ └─────────────────────┘└─┘ └─────
typ └──┘└──────────┘└┘└─────────────┘┴ └─────────────────────┘└─┘ ┴└─────
doc └──┘ └┘ ┴ └─┘ └─────
txt └──┘ └┘ ┴ └─┘ └─────
par └──┘ └┘ ┴ └─┘ └─────
pid └┘ └┘ ┴ └─┘ └─────
st ─────────────────┘└─────────────────────────────────────────────────┘└─
647 list.index_of_nth_le]; refl
id └──────────────────┘
src ─────┘└──────────────────┘┴ └───┘
typ ─────┘└──────────────────┘┴ └───┘
doc ─────┘ ┴ └───┘
txt ─────┘ ┴ └───┘
par ─────┘ ┴ └───┘
pid ─────┘ ┴ ┴
st ─────────────────────────┘┴└─────┘
648 end
st └─┘
649
650 theorem nat_bodd_div2 : primrec nat.bodd_div2 :=
id └─────┘ └───────────┘
src └─────┘ └───────────┘
typ └─────┘ └───────────┘
doc └─────┘
651 (nat_elim' primrec.id (const (ff, 0))
id └───────┘ └────────┘ └───┘ ┴└┘
src └───────┘ └────────┘ └───┘ ┴└┘
typ └───────┘ └────────┘ └───┘ ┴└┘
652 (((cond fst
id └──┘ └─┘
src └──┘ └─┘
typ └──┘ └─┘
653 (pair (const ff) (succ.comp snd))
id └──┘ └───┘ └┘ └──┘└───┘ └─┘
src └──┘ └───┘ └┘ └──┘└───┘ └─┘
typ └──┘ └───┘ └┘ └──┘└───┘ └─┘
654 (pair (const tt) snd)).comp snd).comp snd).to₂).of_eq $
id └──┘ └───┘ └┘ └─┘ └──┘ └─┘ └──┘ └─┘ └─┘ └───┘
src └──┘ └───┘ └┘ └─┘ └──┘ └─┘ └──┘ └─┘ └─┘ └───┘
typ └──┘ └───┘ └┘ └─┘ └──┘ └─┘ └──┘ └─┘ └─┘ └───┘
655 λ n, begin
id ┴
typ ┴
st └─────
656 simp [-nat.bodd_div2_eq],
src └──────────────────────┘
typ └──────────────────────┘
doc └──────────────────────┘
txt └──────────────────────┘
par └──────────────────────┘
pid ┴└─────────────────┘
st ─────────────────────────┘└─
657 induction n with n IH, {refl},
id ┴
src └────────┘ └────────┘ └──┘
typ └────────┘┴└────────┘ └──┘
doc └────────┘ └────────┘ └──┘
txt └────────┘ └────────┘ └──┘
par └────────┘ └────────┘ └──┘
pid ┴ ┴└───────┘
st ──────────────────────┘└─────┘└┘└
658 simp [-nat.bodd_div2_eq, nat.bodd_div2, *],
id └───────────┘
src └───────────────────────┘└───────────┘└──┘
typ └───────────────────────┘└───────────┘└──┘
doc └───────────────────────┘ └──┘
txt └───────────────────────┘ └──┘
par └───────────────────────┘ └──┘
pid ┴└──────────────────┘ └──┘
st ───────────────────────────────────────────┘└─
659 rcases nat.bodd_div2 n with ⟨_|_, m⟩; simp [nat.bodd_div2]
id └───────────┘ ┴ └───────────┘
src └─────┘└───────────┘┴ └────────────┘ └────┘└───────────┘└┘
typ └─────┘└───────────┘┴┴└────────────┘ └────┘└───────────┘└┘
doc └─────┘ ┴ └────────────┘ └────┘ └┘
txt └─────┘ ┴ └────────────┘ └────┘ └┘
par └─────┘ ┴ └────────────┘ └────┘ └┘
pid ┴ ┴ └────────────┘ ┴┴ ┴┴
st ────────────────────────────────────────────────────────────┘
660 end
st └─┘
661
662 theorem nat_bodd : primrec nat.bodd := fst.comp nat_bodd_div2
id └─────┘ └──────┘ └─┘└───┘ └───────────┘
src └─────┘ └──────┘ └─┘└───┘ └───────────┘
typ └─────┘ └──────┘ └─┘└───┘ └───────────┘
doc └─────┘
663 theorem nat_div2 : primrec nat.div2 := snd.comp nat_bodd_div2
id └─────┘ └──────┘ └─┘└───┘ └───────────┘
src └─────┘ └──────┘ └─┘└───┘ └───────────┘
typ └─────┘ └──────┘ └─┘└───┘ └───────────┘
doc └─────┘
664
665 theorem nat_bit0 : primrec (@bit0 ℕ _) :=
id └─────┘ └──┘ ┴
src └─────┘ └──┘ ┴
typ └─────┘ └──┘ ┴
doc └─────┘
666 nat_add.comp primrec.id primrec.id
id └─────┘└───┘ └────────┘ └────────┘
src └─────┘└───┘ └────────┘ └────────┘
typ └─────┘└───┘ └────────┘ └────────┘
667
668 theorem nat_bit1 : primrec (@bit1 ℕ _ _) :=
id └─────┘ └──┘ ┴
src └─────┘ └──┘ ┴
typ └─────┘ └──┘ ┴
doc └─────┘
669 nat_add.comp nat_bit0 (const 1)
id └─────┘└───┘ └──────┘ └───┘
src └─────┘└───┘ └──────┘ └───┘
typ └─────┘└───┘ └──────┘ └───┘
670
671 theorem nat_bit : primrec₂ nat.bit :=
id └──────┘ └─────┘
src └──────┘ └─────┘
typ └──────┘ └─────┘
doc └──────┘
672 (cond primrec.fst
id └──┘ └─────────┘
src └──┘ └─────────┘
typ └──┘ └─────────┘
673 (nat_bit1.comp primrec.snd)
id └──────┘└───┘ └─────────┘
src └──────┘└───┘ └─────────┘
typ └──────┘└───┘ └─────────┘
674 (nat_bit0.comp primrec.snd)).of_eq $
id └──────┘└───┘ └─────────┘ └───┘
src └──────┘└───┘ └─────────┘ └───┘
typ └──────┘└───┘ └─────────┘ └───┘
675 λ n, by cases n.1; refl
id ┴ ┴
src └────┘ └┘ └────
typ ┴ └────┘┴└┘ └────
doc └────┘ └┘ └────
txt └────┘ └┘ └────
par └────┘ └┘ └────
pid ┴ └┘ └
st └────────────────
676
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
677 theorem nat_div_mod : primrec₂ (λ n k : ℕ, (n / k, n % k)) :=
id └──────┘ ┴ ┴┴ ┴ ┴ ┴ ┴ ┴
src └──────┘ ┴ ┴ ┴ ┴
typ └──────┘ ┴ ┴┴ ┴ ┴ ┴ ┴ ┴
doc └──────┘
678 let f (a : ℕ × ℕ) : ℕ × ℕ := a.1.elim (0, 0) (λ _ IH,
id ┴ ┴ ┴ ┴ ┴ ┴ ┴┴ └──┘ ┴ ┴ └┘
src ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴┴ └──┘ ┴ ┴ └┘
679 if nat.succ IH.2 = a.2
id └──────┘ └┘┴ ┴ ┴┴
src └──────┘ ┴ ┴ ┴
typ └──────┘ └┘┴ ┴ ┴┴
680 then (nat.succ IH.1, 0)
id ┴└──────┘ └┘┴
src ┴└──────┘ ┴
typ ┴└──────┘ └┘┴
681 else (IH.1, nat.succ IH.2)) in
id ┴└┘┴ └──────┘ └┘┴
src ┴ ┴ └──────┘ ┴
typ ┴└┘┴ └──────┘ └┘┴
682 have hf : primrec f, from
id └─────┘ ┴
src └─────┘
typ └─────┘ ┴
doc └─────┘
683 nat_elim' fst (const (0, 0)) $
id └───────┘ └─┘ └───┘ ┴
src └───────┘ └─┘ └───┘ ┴
typ └───────┘ └─┘ └───┘ ┴
684 ((ite ((@primrec.eq ℕ _ _).comp (succ.comp $ snd.comp snd) fst)
id └─┘ └────────┘ ┴ └──┘ └──┘└───┘ └─┘└───┘ └─┘ └─┘
src └─┘ └────────┘ ┴ └──┘ └──┘└───┘ └─┘└───┘ └─┘ └─┘
typ └─┘ └────────┘ ┴ └──┘ └──┘└───┘ └─┘└───┘ └─┘ └─┘
685 (pair (succ.comp $ fst.comp snd) (const 0))
id └──┘ └──┘└───┘ └─┘└───┘ └─┘ └───┘
src └──┘ └──┘└───┘ └─┘└───┘ └─┘ └───┘
typ └──┘ └──┘└───┘ └─┘└───┘ └─┘ └───┘
686 (pair (fst.comp snd) (succ.comp $ snd.comp snd)))
id └──┘ └─┘└───┘ └─┘ └──┘└───┘ └─┘└───┘ └─┘
src └──┘ └─┘└───┘ └─┘ └──┘└───┘ └─┘└───┘ └─┘
typ └──┘ └─┘└───┘ └─┘ └──┘└───┘ └─┘└───┘ └─┘
687 .comp (pair (snd.comp fst) (snd.comp snd))).to₂,
id └──┘ └──┘ └─┘└───┘ └─┘ └─┘└───┘ └─┘ └─┘
src └──┘ └──┘ └─┘└───┘ └─┘ └─┘└───┘ └─┘ └─┘
typ └──┘ └──┘ └─┘└───┘ └─┘ └─┘└───┘ └─┘ └─┘
688 suffices ∀ k n, (n / k, n % k) = f (n, k),
id ┴ ┴ ┴┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴┴ ┴
src ┴ ┴ ┴ ┴ ┴
typ ┴ ┴ ┴┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴┴ ┴
689 from hf.of_eq $ λ ⟨m, n⟩, by simp [this],
id └┘└────┘ ┴ └──┘
src └────┘ └────┘ ┴
typ └┘└────┘ ┴ └────┘└──┘┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴┴ ┴
st └──────────┘
690 λ k n, begin
id ┴ ┴
typ ┴ ┴
st └─────
691 have : (f (n, k)).2 + k * (f (n, k)).1 = n
id ┴ ┴ ┴
src └─────┘ ┴ └┘ └───┘┴┴ ┴┴┴ ┴ └┘ └───┘┴┴ └
typ └─────┘ ┴ └┘ └───┘┴┴ ┴┴┴ ┴ └┘ └───┘┴┴ └
doc └─────┘ ┴ └┘ └───┘ ┴ ┴ ┴ ┴ └┘ └───┘ ┴ └
txt └─────┘ ┴ └┘ └───┘ ┴ ┴ ┴ ┴ └┘ └───┘ ┴ └
par └─────┘ ┴ └┘ └───┘ ┴ ┴ ┴ ┴ └┘ └───┘ ┴ └
pid └───┘└┘ ┴ └┘ └───┘ ┴ ┴ ┴ ┴ └┘ └───┘ ┴ └
st ─────────────────────────────────────────────
692 ∧ (0 < k → (f (n, k)).2 < k)
id ┴ ┴
src ───┘┴┴ └┘┴┴ ┴ ┴ ┴ └┘ └───┘ ┴ └─
typ ───┘┴┴ └┘┴┴ ┴ ┴ ┴ └┘ └───┘ ┴ └─
doc ───┘ ┴ └┘ ┴ ┴ ┴ ┴ └┘ └───┘ ┴ └─
txt ───┘ ┴ └┘ ┴ ┴ ┴ ┴ └┘ └───┘ ┴ └─
par ───┘ ┴ └┘ ┴ ┴ ┴ ┴ └┘ └───┘ ┴ └─
pid ───┘ ┴ └┘ ┴ ┴ ┴ ┴ └┘ └───┘ ┴ └─
st ─────────────────────────────────
693 ∧ (k = 0 → (f (n, k)).1 = 0),
id ┴ ┴ ┴┴ ┴
src ───┘ ┴ ┴ └─┘ ┴ ┴┴ └┘ └───┘ └─┘
typ ───┘ ┴ ┴┴└─┘ ┴ ┴┴┴┴└┘┴└───┘ └─┘
doc ───┘ ┴ ┴ └─┘ ┴ ┴ └┘ └───┘ └─┘
txt ───┘ ┴ ┴ └─┘ ┴ ┴ └┘ └───┘ └─┘
par ───┘ ┴ ┴ └─┘ ┴ ┴ └┘ └───┘ └─┘
pid ───┘ ┴ ┴ └─┘ ┴ ┴ └┘ └───┘ └─┘
st ───────────────────────────────┘└─
694 { induction n with n IH, {exact ⟨rfl, id, λ _, rfl⟩},
id ┴ └┘ └─┘
src └────────┘ └────────┘ └────┘ └┘└┘└┘ └──┘└─┘┴
typ └────────┘┴└────────┘ └────┘ └┘└┘└┘ └──┘└─┘┴
doc └────────┘ └────────┘ └────┘ └┘ └┘ └──┘ ┴
txt └────────┘ └────────┘ └────┘ └┘ └┘ └──┘ ┴
par └────────┘ └────────┘ └────┘ └┘ └┘ └──┘ ┴
pid ┴ ┴└───────┘ ┴ └┘ └┘ └──┘ ┴
st ───┘└───────────────────┘└──────────────────────────┘└┘└
695 rw [λ n:ℕ, show f (n.succ, k) =
id └───┘ ┴
src └──┘ └─┘ └┘ ┴ ┴ └───┘└┘ └┘ └
typ └──┘ └─┘ └┘ ┴ ┴ └───┘└┘ └┘┴└
doc └──┘ └─┘ └┘ ┴ ┴ └┘ └┘ └
txt └──┘ └─┘ └┘ ┴ ┴ └┘ └┘ └
par └──┘ └─┘ └┘ ┴ ┴ └┘ └┘ └
pid └┘ └─┘ └┘ ┴ ┴ └┘ └┘ └
st ────────────────────────────────────
696 _root_.ite ((f (n, k)).2.succ = k)
id └────────┘
src ─────┘└────────┘┴ ┴ └┘ └────────┘ ┴ └─
typ ─────┘└────────┘┴ ┴ └┘ └────────┘ ┴ └─
doc ─────┘ ┴ ┴ └┘ └────────┘ ┴ └─
txt ─────┘ ┴ ┴ └┘ └────────┘ ┴ └─
par ─────┘ ┴ ┴ └┘ └────────┘ ┴ └─
pid ─────┘ ┴ ┴ └┘ └────────┘ ┴ └─
st ─────────────────────────────────────────
697 (nat.succ (f (n, k)).1, 0)
id └──────┘
src ─────┘ └──────┘┴ ┴ └┘ └────────
typ ─────┘ └──────┘┴ ┴ └┘ └────────
doc ─────┘ ┴ ┴ └┘ └────────
txt ─────┘ ┴ ┴ └┘ └────────
par ─────┘ ┴ ┴ └┘ └────────
pid ─────┘ ┴ ┴ └┘ └────────
st ─────────────────────────────────
698 ((f (n, k)).1, (f (n, k)).2.succ), from rfl],
id ┴ ┴ ┴ └─┘
src ─────┘ ┴ └┘ └────┘ ┴┴ └┘ └───────────────┘└─┘┴
typ ─────┘ ┴ └┘ └────┘ ┴┴┴ └┘┴└───────────────┘└─┘┴
doc ─────┘ ┴ └┘ └────┘ ┴ └┘ └───────────────┘ ┴
txt ─────┘ ┴ └┘ └────┘ ┴ └┘ └───────────────┘ ┴
par ─────┘ ┴ └┘ └────┘ ┴ └┘ └───────────────┘ ┴
pid ─────┘ ┴ └┘ └────┘ ┴ └┘ └───────────────┘ ┴
st ────────────────────────────────────────────────┘┴└─
699 by_cases h : (f (n, k)).2.succ = k; simp [h],
id ┴ ┴┴ ┴ ┴
src └───────┘ └─┘ ┴┴ └┘ └────────┘ ┴ └────┘ ┴
typ └───────┘ └─┘ ┴┴┴┴└┘ └────────┘ ┴┴ └────┘┴┴
doc └───────┘ └─┘ ┴ └┘ └────────┘ ┴ └────┘ ┴
txt └───────┘ └─┘ ┴ └┘ └────────┘ ┴ └────┘ ┴
par └───────┘ └─┘ ┴ └┘ └────────┘ ┴ └────┘ ┴
pid ┴ └─┘ ┴ └┘ └────────┘ ┴ ┴┴ ┴
st ───────────────────────────────────────────────┘└─
700 { have := congr_arg nat.succ IH.1,
id └───────┘ └──────┘ └┘
src └──────┘└───────┘┴└──────┘┴ └┘
typ └──────┘└───────┘┴└──────┘┴└┘└┘
doc └──────┘ ┴ ┴ └┘
txt └──────┘ ┴ ┴ └┘
par └──────┘ ┴ ┴ └┘
pid └───┘└─┘ ┴ ┴ └┘
st ─────┘└─────────────────────────────┘└─
701 refine ⟨_, λ k0, nat.no_confusion (h.trans k0)⟩,
id └──────────────┘ └─────┘
src └─────┘ └─┘ └───┘└──────────────┘┴ └─────┘┴ └┘
typ └─────┘ └─┘ └───┘└──────────────┘┴ └─────┘┴ └┘
doc └─────┘ └─┘ └───┘ ┴ ┴ └┘
txt └─────┘ └─┘ └───┘ ┴ ┴ └┘
par └─────┘ └─┘ └───┘ ┴ ┴ └┘
pid ┴ └─┘ └───┘ ┴ ┴ └┘
st ────────────────────────────────────────────────────┘└─
702 rwa [← nat.succ_add, h, add_comm, ← nat.mul_succ] at this },
id └──────────┘ ┴ └──────┘ └──────────┘
src └─────┘└──────────┘└┘ └┘└──────┘└──┘└──────────┘└────────┘
typ └─────┘└──────────┘└┘┴└┘└──────┘└──┘└──────────┘└────────┘
doc └─────┘ └┘ └┘ └──┘ └────────┘
txt └─────┘ └┘ └┘ └──┘ └────────┘
par └─────┘ └┘ └┘ └──┘ └────────┘
pid └──┘ └┘ └┘ └──┘ ┴└──────┘┴
st ────────────────────────┘└─┘└────────┘└──────────────┘┴└───────┘└┘└
703 { exact ⟨by rw [nat.succ_add, IH.1],
id └──────────┘ └┘
src └────┘ ┴└──┘└──────────┘└┘ └─┘└─
typ └────┘ ┴└──┘└──────────┘└┘└┘└─┘└─
doc └────┘ ┴└──┘ └┘ └─┘└─
txt └────┘ ┴└──┘ └┘ └─┘└─
par └────┘ ┴└──┘ └┘ └─┘└─
pid ┴ └───┘ └┘ └────
st ──────────────┘└───────────────┘└──┘└─┘└─
704 λ k0, lt_of_le_of_ne (IH.2.1 k0) h, IH.2.2⟩ } },
id └────────────┘ ┴ └┘
src ───────┘ └───┘└────────────┘┴ └───┘ └┘ └┘ └────┘
typ ───────┘ └───┘└────────────┘┴ └───┘ └┘┴└┘└┘└────┘
doc ───────┘ └───┘ ┴ └───┘ └┘ └┘ └────┘
txt ───────┘ └───┘ ┴ └───┘ └┘ └┘ └────┘
par ───────┘ └───┘ ┴ └───┘ └┘ └┘ └────┘
pid ───────┘ └───┘ ┴ └───┘ └┘ └┘ └───┘┴
st ───────────────────────────────────────────────────┘└──┘└
705 revert this, cases f (n, k) with D M,
id ┴ ┴┴ ┴
src └─────────┘ └────┘ ┴┴ └┘ └────────┘
typ └─────────┘ └────┘┴┴┴┴└┘┴└────────┘
doc └─────────┘ └────┘ ┴ └┘ └────────┘
txt └─────────┘ └────┘ ┴ └┘ └────────┘
par └─────────┘ └────┘ ┴ └┘ └────────┘
pid └───┘ ┴ ┴ └┘ ┴└───────┘
st ────────────┘└───────────────────────┘└─
706 simp, intros h₁ h₂ h₃,
src └──┘ └─────────────┘
typ └──┘ └─────────────┘
doc └──┘ └─────────────┘
txt └──┘ └─────────────┘
par └──┘ └─────────────┘
pid └───────┘
st ─────┘└───────────────┘└─
707 cases nat.eq_zero_or_pos k,
id └────────────────┘ ┴
src └────┘└────────────────┘┴
typ └────┘└────────────────┘┴┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴ ┴
st ───────────────────────────┘└─
708 { simp [h, h₃ h] at h₁ ⊢, simp [h₁] },
id ┴ └┘ ┴ └┘
src └────┘ └┘ ┴ └───────┘ └────┘ └┘
typ └────┘┴└┘└┘┴┴└───────┘ └────┘└┘└┘
doc └────┘ └┘ ┴ └───────┘ └────┘ └┘
txt └────┘ └┘ ┴ └───────┘ └────┘ └┘
par └────┘ └┘ ┴ └───────┘ └────┘ └┘
pid ┴┴ └┘ ┴ ┴┴└─────┘ ┴┴ ┴┴
st ───┘└────────────────────┘└──────────┘└┘└
709 { exact (nat.div_mod_unique h).2 ⟨h₁, h₂ h⟩ }
id └────────────────┘ └┘ └┘ ┴
src └────┘ └────────────────┘┴ └──┘ └┘ ┴ └┘
typ └────┘ └────────────────┘┴ └──┘ └┘└┘└┘┴┴└┘
doc └────┘ ┴ └──┘ └┘ ┴ └┘
txt └────┘ ┴ └──┘ └┘ ┴ └┘
par └────┘ ┴ └──┘ └┘ ┴ └┘
pid ┴ ┴ └──┘ └┘ ┴ ┴┴
st ─────────────────────────────────────────────┘└─
710 end
st ──┘
711
712 theorem nat_div : primrec₂ ((/) : ℕ → ℕ → ℕ) := fst.comp₂ nat_div_mod
id └──────┘ ┴ ┴ ┴ ┴ └─┘└────┘ └─────────┘
src └──────┘ ┴ ┴ ┴ ┴ └─┘└────┘ └─────────┘
typ └──────┘ ┴ ┴ ┴ ┴ └─┘└────┘ └─────────┘
doc └──────┘
713 theorem nat_mod : primrec₂ ((%) : ℕ → ℕ → ℕ) := snd.comp₂ nat_div_mod
id └──────┘ ┴ ┴ ┴ ┴ └─┘└────┘ └─────────┘
src └──────┘ ┴ ┴ ┴ ┴ └─┘└────┘ └─────────┘
typ └──────┘ ┴ ┴ ┴ ┴ └─┘└────┘ └─────────┘
doc └──────┘
714
715 end primrec
716
717 section
718 variables {α : Type*} {β : Type*} {σ : Type*}
id ┴ ┴
typ ┴ ┴
719 variables [primcodable α] [primcodable β] [primcodable σ]
id └─────────┘ ┴└─────────┘ └─────────┘
src └─────────┘ └─────────┘ └─────────┘
typ └─────────┘ ┴└─────────┘ └─────────┘
doc └─────────┘ └─────────┘ └─────────┘
720
721 variable (H : nat.primrec (λ n, encodable.encode (decode (list β) n)))
id └─────────┘ ┴ └──────────────┘ └────┘ └──┘ ┴
src └─────────┘ └──────────────┘ └────┘ └──┘
typ └─────────┘ ┴ └──────────────┘ └────┘ └──┘ ┴
doc └─────────┘
722 include H
723 open primrec
724
725 private def prim : primcodable (list β) := ⟨H⟩
id └─────────┘ └──┘ ┴ ┴
src └─────────┘ └──┘
typ └─────────┘ └──┘ ┴ ┴
doc └─────────┘
726
727 private lemma list_cases'
728 {f : α → list β} {g : α → σ} {h : α → β × list β → σ}
id ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ ┴
src └──┘ ┴ └──┘
typ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ ┴
729 (hf : by haveI := prim H; exact primrec f) (hg : primrec g)
id └──┘ ┴ └─────┘ ┴ └─────┘ ┴
src └───────┘└──┘┴ └────┘└─────┘┴ └─────┘
typ └───────┘└──┘┴┴ └────┘└─────┘┴┴ └─────┘ ┴
doc └───────┘ ┴ └────┘└─────┘┴ └─────┘
txt └───────┘ ┴ └────┘ ┴
par └───────┘ ┴ └────┘ ┴
pid ┴└─┘ ┴ ┴ ┴
st └───────────────────────────────┘
730 (hh : by haveI := prim H; exact primrec₂ h) :
id └──┘ ┴ └──────┘ ┴
src └───────┘└──┘┴ └────┘└──────┘┴
typ └───────┘└──┘┴┴ └────┘└──────┘┴┴
doc └───────┘ ┴ └────┘└──────┘┴
txt └───────┘ ┴ └────┘ ┴
par └───────┘ ┴ └────┘ ┴
pid ┴└─┘ ┴ ┴ ┴
st └────────────────────────────────┘
731 @primrec _ σ _ _ (λ a, list.cases_on (f a) (g a) (λ b l, h a (b, l))) :=
id └─────┘ ┴ ┴ └───────────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴┴ ┴
src └─────┘ └───────────┘ ┴
typ └─────┘ ┴ ┴ └───────────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴┴ ┴
doc └─────┘
732 by letI := prim H; exact
id └──┘ ┴
src └──────┘└──┘┴ └────┘
typ └──────┘└──┘┴┴ └────┘
doc └──────┘ ┴ └────┘
txt └──────┘ ┴ └────┘
par └──────┘ ┴ └────┘
pid ┴└─┘ ┴ ┴
st └──────────────────────
733 have @primrec _ (option σ) _ _ (λ a,
id └─────┘ ┴
src ┴ └─────┘└─┘ ┴ └────┘ └───
typ ┴ └─────┘└─┘ ┴┴└────┘ └───
doc ┴ └─────┘└─┘ ┴ └────┘ └───
txt ┴ └─┘ ┴ └────┘ └───
par ┴ └─┘ ┴ └────┘ └───
pid ┴ └─┘ ┴ └────┘ └───
st ─────────────────────────────────────
734 (decode (option (β × list β)) (encode (f a))).map
id └────┘ ┴ └────┘ ┴
src ─┘ └────┘┴ ┴ ┴┴┴ ┴ └─┘ └────┘┴ ┴ └───────
typ ─┘ └────┘┴ ┴ ┴┴┴ ┴ └─┘ └────┘┴ ┴┴ └───────
doc ─┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ └───────
txt ─┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ └───────
par ─┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ └───────
pid ─┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ └───────
st ────────────────────────────────────────────────────
735 (λ o, option.cases_on o (g a) (h a))), from
id └─────────────┘ ┴ ┴
src ─┘ └──┘└─────────────┘┴ ┴ ┴ └┘ ┴ └────────┘
typ ─┘ └──┘└─────────────┘┴ ┴ ┴┴ └┘ ┴┴ └────────┘
doc ─┘ └──┘ ┴ ┴ ┴ └┘ ┴ └────────┘
txt ─┘ └──┘ ┴ ┴ ┴ └┘ ┴ └────────┘
par ─┘ └──┘ ┴ ┴ ┴ └┘ ┴ └────────┘
pid ─┘ └──┘ ┴ ┴ ┴ └┘ ┴ └────────┘
st ──────────────────────────────────────────────
736 ((@map_decode_iff _ (option (β × list β)) _ _ _ _ _).2 $
id └────────────┘ └────┘ └──┘ ┴
src └────────────┘└─┘ └────┘┴ ┴ ┴└──┘┴ └──────────────┘ └
typ └────────────┘└─┘ └────┘┴ ┴ ┴└──┘┴┴└──────────────┘ └
doc └─┘ ┴ ┴ ┴ ┴ └──────────────┘ └
txt └─┘ ┴ ┴ ┴ ┴ └──────────────┘ └
par └─┘ ┴ ┴ ┴ ┴ └──────────────┘ └
pid └─┘ ┴ ┴ ┴ ┴ └──────────────┘ └
st ─────────────────────────────────────────────────────────
737 to₂ $ option_cases snd (hg.comp fst)
id └─┘ └──────────┘ └─┘ └─────┘
src ───┘└─┘┴ ┴└──────────┘┴└─┘┴ └─────┘┴ └─
typ ───┘└─┘┴ ┴└──────────┘┴└─┘┴ └─────┘┴ └─
doc ───┘ ┴ ┴ ┴ ┴ ┴ └─
txt ───┘ ┴ ┴ ┴ ┴ ┴ └─
par ───┘ ┴ ┴ ┴ ┴ ┴ └─
pid ───┘ ┴ ┴ ┴ ┴ ┴ └─
st ─────────────────────────────────────────
738 (hh.comp₂ (fst.comp₂ primrec₂.left) primrec₂.right))
id └──────┘ └───────┘ └───────────┘ └────────────┘
src ─┘ └──────┘┴ └───────┘┴└───────────┘└┘└────────────┘└──
typ ─┘ └──────┘┴ └───────┘┴└───────────┘└┘└────────────┘└──
doc ─┘ ┴ ┴ └┘ └──
txt ─┘ ┴ ┴ └┘ └──
par ─┘ ┴ ┴ └┘ └──
pid ─┘ ┴ ┴ └┘ └──
st ───────────────────────────────────────────────────────
739 .comp primrec.id (encode_iff.2 hf),
id └────────┘ └────────┘ └┘
src ─────────┘└────────┘┴ └────────┘└─┘ └─┘
typ ─────────┘└────────┘┴ └────────┘└─┘└┘└─┘
doc ─────────┘ ┴ └─┘ └─┘
txt ─────────┘ ┴ └─┘ └─┘
par ─────────┘ ┴ └─┘ └─┘
pid ─────────┘ ┴ └─┘ └─┘
st ────────────────────────────────────────
740 option_some_iff.1 $ this.of_eq $
id └─────────────┘ └────┘
src └─────────────┘└─┘ ┴ └────┘┴ ┴
typ └─────────────┘└─┘ ┴ └────┘┴ ┴
doc └─┘ ┴ ┴ ┴
txt └─┘ ┴ ┴ ┴
par └─┘ ┴ ┴ ┴
pid └─┘ ┴ ┴ ┴
st ─────────────────────────────────
741 λ a, by cases f a with b l; simp [encodek]; refl
id ┴ ┴ └─────┘
src └──┘ ┴└────┘ ┴ └───────┘└┘└────┘└─────┘┴└┘└────
typ └──┘ ┴└────┘┴┴┴└───────┘└┘└────┘└─────┘┴└┘└────
doc └──┘ ┴└────┘ ┴ └───────┘└┘└────┘ ┴└┘└────
txt └──┘ ┴└────┘ ┴ └───────┘└┘└────┘ ┴└┘└────
par └──┘ ┴└────┘ ┴ └───────┘└┘└────┘ ┴└┘└────
pid └──┘ └─────┘ ┴ └───────────────┘ └───────
st ──────┘└─────────────────────────────────────────
742
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
743 private lemma list_foldl'
744 {f : α → list β} {g : α → σ} {h : α → σ × β → σ}
id ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴
typ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
745 (hf : by haveI := prim H; exact primrec f) (hg : primrec g)
id └──┘ ┴ └─────┘ ┴ └─────┘ ┴
src └───────┘└──┘┴ └────┘└─────┘┴ └─────┘
typ └───────┘└──┘┴┴ └────┘└─────┘┴┴ └─────┘ ┴
doc └───────┘ ┴ └────┘└─────┘┴ └─────┘
txt └───────┘ ┴ └────┘ ┴
par └───────┘ ┴ └────┘ ┴
pid ┴└─┘ ┴ ┴ ┴
st └───────────────────────────────┘
746 (hh : by haveI := prim H; exact primrec₂ h) :
id └──┘ ┴ └──────┘ ┴
src └───────┘└──┘┴ └────┘└──────┘┴
typ └───────┘└──┘┴┴ └────┘└──────┘┴┴
doc └───────┘ ┴ └────┘└──────┘┴
txt └───────┘ ┴ └────┘ ┴
par └───────┘ ┴ └────┘ ┴
pid ┴└─┘ ┴ ┴ ┴
st └────────────────────────────────┘
747 primrec (λ a, (f a).foldl (λ s b, h a (s, b)) (g a)) :=
id └─────┘ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴ ┴
src └─────┘ └───┘ ┴
typ └─────┘ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴ ┴
doc └─────┘
748 by letI := prim H; exact
id └──┘ ┴
src └──────┘└──┘┴ └────┘
typ └──────┘└──┘┴┴ └────┘
doc └──────┘ ┴ └────┘
txt └──────┘ ┴ └────┘
par └──────┘ ┴ └────┘
pid ┴└─┘ ┴ ┴
st └──────────────────────
749 let G (a : α) (IH : σ × list β) : σ × list β :=
id ┴ ┴ ┴ └──┘ ┴
src └──────┘ └──────┘ ┴┴┴ ┴ └──┘ ┴ ┴└──┘┴ └───
typ └──────┘ └──────┘ ┴┴┴ ┴ └──┘┴┴┴┴└──┘┴┴└───
doc └──────┘ └──────┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ └───
txt └──────┘ └──────┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ └───
par └──────┘ └──────┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ └───
pid └──────┘ └──────┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ └───
st ────────────────────────────────────────────────
750 list.cases_on IH.2 IH (λ b l, (h a (IH.1, b), l)) in
id └───────────┘ ┴┴
src ─┘└───────────┘┴ └─┘ ┴ └────┘┴ ┴ ┴ └──┘ └─┘ └────┘
typ ─┘└───────────┘┴ └─┘ ┴ └────┘┴┴┴ ┴ └──┘ └─┘ └────┘
doc ─┘ ┴ └─┘ ┴ └────┘ ┴ ┴ └──┘ └─┘ └────┘
txt ─┘ ┴ └─┘ ┴ └────┘ ┴ ┴ └──┘ └─┘ └────┘
par ─┘ ┴ └─┘ ┴ └────┘ ┴ ┴ └──┘ └─┘ └────┘
pid ─┘ ┴ └─┘ ┴ └────┘ ┴ ┴ └──┘ └─┘ └────┘
st ───────────────────────────────────────────────────────
751 let F (a : α) (n : ℕ) := nat.iterate (G a) n (g a, f a) in
id ┴ └─────────┘ ┴
src └──────┘ └─────┘ └───┘└─────────┘┴ ┴ └┘ ┴ ┴ └┘ ┴ └───┘
typ └──────┘┴└─────┘ └───┘└─────────┘┴ ┴ └┘ ┴ ┴┴ └┘ ┴ └───┘
doc └──────┘ └─────┘ └───┘ ┴ ┴ └┘ ┴ ┴ └┘ ┴ └───┘
txt └──────┘ └─────┘ └───┘ ┴ ┴ └┘ ┴ ┴ └┘ ┴ └───┘
par └──────┘ └─────┘ └───┘ ┴ ┴ └┘ ┴ ┴ └┘ ┴ └───┘
pid └──────┘ └─────┘ └───┘ ┴ ┴ └┘ ┴ ┴ └┘ ┴ └───┘
st ───────────────────────────────────────────────────────────
752 have primrec (λ a, (F a (encode (f a))).1), from
id └────┘ ┴
src └───────┘ └──┘ ┴ ┴ └────┘┴ ┴ └───────────┘
typ └───────┘ └──┘ ┴ ┴ └────┘┴ ┴┴ └───────────┘
doc └───────┘ └──┘ ┴ ┴ ┴ ┴ └───────────┘
txt └───────┘ └──┘ ┴ ┴ ┴ ┴ └───────────┘
par └───────┘ └──┘ ┴ ┴ ┴ ┴ └───────────┘
pid └───────┘ └──┘ ┴ ┴ ┴ ┴ └───────────┘
st ─────────────────────────────────────────────────
753 fst.comp $ nat_iterate (encode_iff.2 hf) (pair hg hf) $
id └─────────┘ └────────┘ └┘ └┘
src ┴ ┴└─────────┘┴ └────────┘└─┘ └┘ ┴ ┴ └┘ └
typ ┴ ┴└─────────┘┴ └────────┘└─┘ └┘ ┴└┘┴└┘└┘ └
doc ┴ ┴ ┴ └─┘ └┘ ┴ ┴ └┘ └
txt ┴ ┴ ┴ └─┘ └┘ ┴ ┴ └┘ └
par ┴ ┴ ┴ └─┘ └┘ ┴ ┴ └┘ └
pid ┴ ┴ ┴ └─┘ └┘ ┴ ┴ └┘ └
st ────────────────────────────────────────────────────────
754 list_cases' H (snd.comp snd) snd $ to₂ $ pair
id └─────────┘ ┴ └─┘
src ─┘└─────────┘┴ ┴ ┴ └┘ ┴ ┴└─┘┴ ┴ └
typ ─┘└─────────┘┴┴┴ ┴ └┘ ┴ ┴└─┘┴ ┴ └
doc ─┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └
txt ─┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └
par ─┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └
pid ─┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └
st ────────────────────────────────────────────────
755 (hh.comp (fst.comp fst) $
id └─────┘
src ───┘ └─────┘┴ ┴ └┘ └
typ ───┘ └─────┘┴ ┴ └┘ └
doc ───┘ ┴ ┴ └┘ └
txt ───┘ ┴ ┴ └┘ └
par ───┘ ┴ ┴ └┘ └
pid ───┘ ┴ ┴ └┘ └
st ──────────────────────────────
756 pair ((fst.comp snd).comp fst) (fst.comp snd))
id └──┘ └──────┘
src ─────┘└──┘┴ ┴ └─────┘ └┘ └──────┘┴ └──
typ ─────┘└──┘┴ ┴ └─────┘ └┘ └──────┘┴ └──
doc ─────┘ ┴ ┴ └─────┘ └┘ ┴ └──
txt ─────┘ ┴ ┴ └─────┘ └┘ ┴ └──
par ─────┘ ┴ ┴ └─────┘ └┘ ┴ └──
pid ─────┘ ┴ ┴ └─────┘ └┘ ┴ └──
st ─────────────────────────────────────────────────────
757 (snd.comp snd),
id └──────┘ └─┘
src ───┘ └──────┘┴└─┘└─┘
typ ───┘ └──────┘┴└─┘└─┘
doc ───┘ ┴ └─┘
txt ───┘ ┴ └─┘
par ───┘ ┴ └─┘
pid ───┘ ┴ └─┘
st ────────────────────
758 this.of_eq $ λ a, begin
id └────┘
src └────┘┴ ┴ └──┘ └
typ └────┘┴ ┴ └──┘ └
doc ┴ ┴ └──┘ └
txt ┴ ┴ └──┘ └
par ┴ ┴ └──┘ └
pid ┴ ┴ └──┘ └
st ─────────────────┘└─────
759 have : ∀ n, F a n =
id ┴ ┴
src ─┘└─────┘ └┘ ┴ ┴ ┴ ┴┴└
typ ─┘└─────┘ └┘ ┴┴┴ ┴ ┴┴└
doc ─┘└─────┘ └┘ ┴ ┴ ┴ ┴ └
txt ─┘└─────┘ └┘ ┴ ┴ ┴ ┴ └
par ─┘└─────┘ └┘ ┴ ┴ ┴ ┴ └
pid ────────┘ └┘ ┴ ┴ ┴ ┴ └
st ──────────────────────
760 ((list.take n (f a)).foldl (λ s b, h a (s, b)) (g a),
id └───────┘ ┴ ┴ ┴
src ───┘ └───────┘┴ ┴ ┴ └───────┘ └────┘ ┴ ┴┴ └┘ └─┘ ┴ └──
typ ───┘ └───────┘┴ ┴ ┴ └───────┘ └────┘┴┴ ┴┴ └┘ └─┘ ┴┴ └──
doc ───┘ ┴ ┴ ┴ └───────┘ └────┘ ┴ ┴ └┘ └─┘ ┴ └──
txt ───┘ ┴ ┴ ┴ └───────┘ └────┘ ┴ ┴ └┘ └─┘ ┴ └──
par ───┘ ┴ ┴ ┴ └───────┘ └────┘ ┴ ┴ └┘ └─┘ ┴ └──
pid ───┘ ┴ ┴ ┴ └───────┘ └────┘ ┴ ┴ └┘ └─┘ ┴ └──
st ──────────────────────────────────────────────────────────
761 list.drop n (f a)),
id └───────┘ ┴ ┴
src ─────┘└───────┘┴ ┴ ┴ └┘└─
typ ─────┘└───────┘┴ ┴ ┴┴┴└┘└─
doc ─────┘ ┴ ┴ ┴ └┘└─
txt ─────┘ ┴ ┴ ┴ └┘└─
par ─────┘ ┴ ┴ ┴ └┘└─
pid ─────┘ ┴ ┴ ┴ └───
st ───────────────────────┘└─
762 { intro, simp [F],
id ┴
src ───┘└───┘└┘└────┘ ┴└─
typ ───┘└───┘└┘└────┘┴┴└─
doc ───┘└───┘└┘└────┘ ┴└─
txt ───┘└───┘└┘└────┘ ┴└─
par ───┘└───┘└┘└────┘ ┴└─
pid ────────────────┘ └──
st ──┘└────┘└────────┘└─
763 generalize : f a = l, generalize : g a = x,
id ┴ ┴ ┴ ┴
src ───┘└───────────┘ ┴ ┴ ┴ └┘└───────────┘ ┴ ┴ ┴ └─
typ ───┘└───────────┘┴┴┴┴ ┴ └┘└───────────┘┴┴┴┴ ┴ └─
doc ───┘└───────────┘ ┴ ┴ ┴ └┘└───────────┘ ┴ ┴ ┴ └─
txt ───┘└───────────┘ ┴ ┴ ┴ └┘└───────────┘ ┴ ┴ ┴ └─
par ───┘└───────────┘ ┴ ┴ ┴ └┘└───────────┘ ┴ ┴ ┴ └─
pid ────────────────┘ ┴ ┴ ┴ └─────────────┘ ┴ ┴ ┴ └─
st ───────────────────────┘└────────────────────┘└─
764 induction n with n IH generalizing l x, {refl},
id ┴
src ───┘└────────┘ └─────────────────────────┘└─┘└──┘└──
typ ───┘└────────┘┴└─────────────────────────┘└─┘└──┘└──
doc ───┘└────────┘ └─────────────────────────┘└─┘└──┘└──
txt ───┘└────────┘ └─────────────────────────┘└─┘└──┘└──
par ───┘└────────┘ └─────────────────────────┘└─┘└──┘└──
pid ─────────────┘ └────────────────────────────────────
st ─────────────────────────────────────────┘└─────┘┴└─
765 simp, cases l with b l; simp [IH] },
id ┴ └┘
src ───┘└──┘└┘└────┘ └───────┘└┘└────┘ └┘└──
typ ───┘└──┘└┘└────┘┴└───────┘└┘└────┘└┘└┘└──
doc ───┘└──┘└┘└────┘ └───────┘└┘└────┘ └┘└──
txt ───┘└──┘└┘└────┘ └───────┘└┘└────┘ └┘└──
par ───┘└──┘└┘└────┘ └───────┘└┘└────┘ └┘└──
pid ───────────────┘ └───────────────┘ └────
st ───────┘└────────────────────────────┘┴└─
766 rw [this, list.take_all_of_le (length_le_encode _)]
id └──┘ └─────────────────┘ └──────────────┘
src ─┘└──┘ └┘└─────────────────┘┴ └──────────────┘└───┘
typ ─┘└──┘└──┘└┘└─────────────────┘┴ └──────────────┘└───┘
doc ─┘└──┘ └┘ ┴ └───┘
txt ─┘└──┘ └┘ ┴ └───┘
par ─┘└──┘ └┘ ┴ └───┘
pid ─────┘ └┘ ┴ └────
st ─────────┘└────────────────────────────────────────┘┴┴
767 end
src └───
typ └───
doc └───
txt └───
par └───
pid ──┘└
st └─┘└
768
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
769 private lemma list_cons' : by haveI := prim H; exact primrec₂ (@list.cons β) :=
id └──┘ ┴ └──────┘ └───────┘ ┴
src └───────┘└──┘┴ └────┘└──────┘┴ └───────┘┴ └┘
typ └───────┘└──┘┴┴ └────┘└──────┘┴ └───────┘┴┴└┘
doc └───────┘ ┴ └────┘└──────┘┴ ┴ └┘
txt └───────┘ ┴ └────┘ ┴ ┴ └┘
par └───────┘ ┴ └────┘ ┴ ┴ └┘
pid ┴└─┘ ┴ ┴ ┴ ┴ ┴┴
st └──────────────────────────────────────────────┘
770 by letI := prim H; exact
id └──┘ ┴
src └──────┘└──┘┴ └────┘
typ └──────┘└──┘┴┴ └────┘
doc └──────┘ ┴ └────┘
txt └──────┘ ┴ └────┘
par └──────┘ ┴ └────┘
pid ┴└─┘ ┴ ┴
st └──────────────────────
771 encode_iff.1 (succ.comp $
id └───────┘
src └─┘ └───────┘┴ ┴
typ └─┘ └───────┘┴ ┴
doc └─┘ ┴ ┴
txt └─┘ ┴ ┴
par └─┘ ┴ ┴
pid └─┘ ┴ ┴
st ──────────────────────────
772 primrec₂.mkpair.comp (encode_iff.2 fst) (encode_iff.2 snd))
id └──────────────────┘ └─┘ └────────┘ └─┘
src └──────────────────┘┴ └─┘└─┘└┘ └────────┘└─┘└─┘└──
typ └──────────────────┘┴ └─┘└─┘└┘ └────────┘└─┘└─┘└──
doc ┴ └─┘ └┘ └─┘ └──
txt ┴ └─┘ └┘ └─┘ └──
par ┴ └─┘ └┘ └─┘ └──
pid ┴ └─┘ └┘ └─┘ └┘└
st ────────────────────────────────────────────────────────────
773
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
774 private lemma list_reverse' : by haveI := prim H; exact
id └──┘ ┴
src └───────┘└──┘┴ └─────
typ └───────┘└──┘┴┴ └─────
doc └───────┘ ┴ └─────
txt └───────┘ ┴ └─────
par └───────┘ ┴ └─────
pid ┴└─┘ ┴ └
st └───────────────────────
775 primrec (@list.reverse β) :=
id └─────┘ └──────────┘ ┴
src ─┘└─────┘┴ └──────────┘┴ └┘
typ ─┘└─────┘┴ └──────────┘┴┴└┘
doc ─┘└─────┘┴ ┴ └┘
txt ─┘ ┴ ┴ └┘
par ─┘ ┴ ┴ └┘
pid ─┘ ┴ ┴ ┴┴
st ───────────────────────────┘
776 by letI := prim H; exact
id └──┘ ┴
src └──────┘└──┘┴ └────┘
typ └──────┘└──┘┴┴ └────┘
doc └──────┘ ┴ └────┘
txt └──────┘ ┴ └────┘
par └──────┘ ┴ └────┘
pid ┴└─┘ ┴ ┴
st └──────────────────────
777 (list_foldl' H primrec.id (const []) $ to₂ $
id └─────────┘ └────────┘ └───┘ └┘ └─┘
src └─────────┘┴ ┴└────────┘┴ └───┘┴└┘└┘ ┴└─┘┴ └
typ └─────────┘┴ ┴└────────┘┴ └───┘┴└┘└┘ ┴└─┘┴ └
doc ┴ ┴ ┴ ┴ └┘ ┴ ┴ └
txt ┴ ┴ ┴ ┴ └┘ ┴ ┴ └
par ┴ ┴ ┴ ┴ └┘ ┴ ┴ └
pid ┴ ┴ ┴ ┴ └┘ ┴ ┴ └
st ─────────────────────────────────────────────
778 ((list_cons' H).comp snd fst).comp snd).of_eq
id └────────┘ ┴ └─┘ └─┘
src ──┘ └────────┘┴ └─────┘ ┴└─┘└─────┘└─┘└──────┘
typ ──┘ └────────┘┴┴└─────┘ ┴└─┘└─────┘└─┘└──────┘
doc ──┘ ┴ └─────┘ ┴ └─────┘ └──────┘
txt ──┘ ┴ └─────┘ ┴ └─────┘ └──────┘
par ──┘ ┴ └─────┘ ┴ └─────┘ └──────┘
pid ──┘ ┴ └─────┘ ┴ └─────┘ └──────┘
st ─────────────────────────────────────────────────
779 (suffices ∀ l r, list.foldl (λ (s : list β) (b : β), b :: s) r l = list.reverse_core l r,
id └────────┘ └──┘ ┴ └┘ ┴ └───────────────┘
src ┴ └──┘ ┴└────────┘┴ └────┘└──┘┴ └─────┘ └─┘ ┴└┘┴ └┘ ┴ ┴┴┴└───────────────┘┴ ┴ └─
typ ┴ └──┘ ┴└────────┘┴ └────┘└──┘┴ └─────┘┴└─┘ ┴└┘┴ └┘ ┴ ┴┴┴└───────────────┘┴ ┴ └─
doc ┴ └──┘ ┴ ┴ └────┘ ┴ └─────┘ └─┘ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ └─
txt ┴ └──┘ ┴ ┴ └────┘ ┴ └─────┘ └─┘ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ └─
par ┴ └──┘ ┴ ┴ └────┘ ┴ └─────┘ └─┘ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ └─
pid ┴ └──┘ ┴ ┴ └────┘ ┴ └─────┘ └─┘ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ └─
st ──────────────────────────────────────────────────────────────────────────────────────────
780 from λ l, this l [],
src ────┘ └──┘ ┴ ┴ └┘
typ ────┘ └──┘ ┴ ┴ └┘
doc ────┘ └──┘ ┴ ┴ └┘
txt ────┘ └──┘ ┴ ┴ └┘
par ────┘ └──┘ ┴ ┴ └┘
pid ────┘ └──┘ ┴ ┴ └┘
st ─────────────────────
781 λ l, by induction l; simp [*, list.reverse_core])
id ┴ └───────────────┘
src └──┘ ┴└────────┘ └┘└───────┘└───────────────┘┴└─
typ └──┘ ┴└────────┘┴└┘└───────┘└───────────────┘┴└─
doc └──┘ ┴└────────┘ └┘└───────┘ ┴└─
txt └──┘ ┴└────────┘ └┘└───────┘ ┴└─
par └──┘ ┴└────────┘ └┘└───────┘ ┴└─
pid └──┘ └─────────┘ └─────────┘ └┘└
st ──────┘└───────────────────────────────────────┘└─
782
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
783 end
784
785 namespace primcodable
786 variables {α : Type*} {β : Type*}
id ┴
typ ┴
787 variables [primcodable α] [primcodable β]
id └─────────┘ └─────────┘
src └─────────┘ └─────────┘
typ └─────────┘ └─────────┘
doc └─────────┘ └─────────┘
788 open primrec
789
790 instance sum : primcodable (α ⊕ β) :=
id └─────────┘ ┴ ┴ ┴
src └─────────┘ ┴
typ └─────────┘ ┴ ┴ ┴
doc └─────────┘
791 ⟨primrec.nat_iff.1 $
id └─────────────┘┴
src └─────────────┘┴
typ └─────────────┘┴
792 (encode_iff.2 (cond nat_bodd
id └────────┘┴ └──┘ └──────┘
src └────────┘┴ └──┘ └──────┘
typ └────────┘┴ └──┘ └──────┘
793 (((@primrec.decode β _).comp nat_div2).option_map $ to₂ $
id └────────────┘ ┴ └──┘ └──────┘ └────────┘ ┴ └─┘
src └────────────┘ └──┘ └──────┘ └────────┘ └─┘
typ └────────────┘ ┴ └──┘ └──────┘ └────────┘ ┴ └─┘
794 nat_bit.comp (const tt) (primrec.encode.comp snd))
id └─────┘└───┘ └───┘ └┘ └────────────┘└───┘ └─┘
src └─────┘└───┘ └───┘ └┘ └────────────┘└───┘ └─┘
typ └─────┘└───┘ └───┘ └┘ └────────────┘└───┘ └─┘
795 (((@primrec.decode α _).comp nat_div2).option_map $ to₂ $
id └────────────┘ ┴ └──┘ └──────┘ └────────┘ └─┘
src └────────────┘ └──┘ └──────┘ └────────┘ └─┘
typ └────────────┘ ┴ └──┘ └──────┘ └────────┘ └─┘
796 nat_bit.comp (const ff) (primrec.encode.comp snd)))).of_eq $
id └─────┘└───┘ └───┘ └┘ └────────────┘└───┘ └─┘ └───┘
src └─────┘└───┘ └───┘ └┘ └────────────┘└───┘ └─┘ └───┘
typ └─────┘└───┘ └───┘ └┘ └────────────┘└───┘ └─┘ └───┘
797 λ n, show _ = encode (decode_sum n), begin
id ┴ ┴ └────┘ └────────┘ ┴
src ┴ └────┘ └────────┘
typ ┴ ┴ └────┘ └────────┘ ┴
st └─────
798 simp [decode_sum],
id └────────┘
src └────┘└────────┘┴
typ └────┘└────────┘┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴┴ ┴
st ──────────────────┘└─
799 cases nat.bodd n; simp [decode_sum],
id └──────┘ ┴ └────────┘
src └────┘└──────┘┴ └────┘└────────┘┴
typ └────┘└──────┘┴┴ └────┘└────────┘┴
doc └────┘ ┴ └────┘ ┴
txt └────┘ ┴ └────┘ ┴
par └────┘ ┴ └────┘ ┴
pid ┴ ┴ ┴┴ ┴
st ────────────────────────────────────┘└─
800 { cases decode α n.div2; refl },
id └────┘ ┴ └────┘
src └────┘└────┘┴ ┴└────┘ └───┘
typ └────┘└────┘┴┴┴└────┘ └───┘
doc └────┘ ┴ ┴ └───┘
txt └────┘ ┴ ┴ └───┘
par └────┘ ┴ ┴ └───┘
pid ┴ ┴ ┴ ┴
st ───┘└──────────────────────────┘└┘└
801 { cases decode β n.div2; refl }
id └────┘ ┴ └────┘
src └────┘└────┘┴ ┴└────┘ └───┘
typ └────┘└────┘┴┴┴└────┘ └───┘
doc └────┘ ┴ ┴ └───┘
txt └────┘ ┴ ┴ └───┘
par └────┘ ┴ ┴ └───┘
pid ┴ ┴ ┴ ┴
st ───────────────────────────────┘└─
802 end⟩
st ──┘
803
804 instance list : primcodable (list α) := ⟨
id └─────────┘ └──┘ ┴
src └─────────┘ └──┘
typ └─────────┘ └──┘ ┴
doc └─────────┘
805 by letI H := primcodable.prim (list ℕ); exact
id └──────────────┘ └──┘
src └────────┘└──────────────┘┴ └──┘┴ ┴ └────┘
typ └────────┘└──────────────┘┴ └──┘┴ ┴ └────┘
doc └────────┘ ┴ ┴ ┴ └────┘
txt └────────┘ ┴ ┴ ┴ └────┘
par └────────┘ ┴ ┴ ┴ └────┘
pid └┘┴└─┘ ┴ ┴ ┴ ┴
st └───────────────────────────────────────────
806 have primrec₂ (λ (a : α) (o : option (list ℕ)),
id └────┘
src └────────┘ └────┘ └─────┘└────┘┴ ┴ └───
typ └────────┘ └────┘ └─────┘└────┘┴ ┴ └───
doc └────────┘ └────┘ └─────┘ ┴ ┴ └───
txt └────────┘ └────┘ └─────┘ ┴ ┴ └───
par └────────┘ └────┘ └─────┘ ┴ ┴ └───
pid └────────┘ └────┘ └─────┘ ┴ ┴ └───
st ────────────────────────────────────────────────
807 o.map (list.cons (encode a))), from
id └──┘
src ─┘ └──┘┴ ┴ ┴ └────────┘
typ ─┘ └──┘┴ ┴ ┴ └────────┘
doc ─┘ ┴ ┴ ┴ └────────┘
txt ─┘ ┴ ┴ ┴ └────────┘
par ─┘ ┴ ┴ ┴ └────────┘
pid ─┘ ┴ ┴ ┴ └────────┘
st ──────────────────────────────────────
808 option_map snd $
id └────────┘
src └────────┘┴ ┴ └
typ └────────┘┴ ┴ └
doc ┴ ┴ └
txt ┴ ┴ └
par ┴ ┴ └
pid ┴ ┴ └
st ─────────────────
809 (list_cons' H).comp ((@primrec.encode α _).comp (fst.comp fst)) snd,
id └────────┘ ┴ └────────────┘ ┴ └──────┘ └─┘ └─┘
src ─┘ └────────┘┴ └─────┘ └────────────┘┴ └───────┘ └──────┘┴└─┘└─┘└─┘└┘
typ ─┘ └────────┘┴┴└─────┘ └────────────┘┴┴└───────┘ └──────┘┴└─┘└─┘└─┘└┘
doc ─┘ ┴ └─────┘ ┴ └───────┘ ┴ └─┘ └┘
txt ─┘ ┴ └─────┘ ┴ └───────┘ ┴ └─┘ └┘
par ─┘ ┴ └─────┘ ┴ └───────┘ ┴ └─┘ └┘
pid ─┘ ┴ └─────┘ ┴ └───────┘ ┴ └─┘ └┘
st ───────────────────────────────────────────────────────────────────────
810 have primrec (λ n, (of_nat (list ℕ) n).reverse.foldl
id └────┘
src └───────┘ └──┘ └────┘┴ ┴ └┘ └───────────────
typ └───────┘ └──┘ └────┘┴ ┴ └┘ └───────────────
doc └───────┘ └──┘ ┴ ┴ └┘ └───────────────
txt └───────┘ └──┘ ┴ ┴ └┘ └───────────────
par └───────┘ └──┘ ┴ ┴ └┘ └───────────────
pid └───────┘ └──┘ ┴ ┴ └┘ └───────────────
st ─────────────────────────────────────────────────────
811 (λ o m, (decode α m).bind (λ a, o.map (list.cons (encode a))))
id └────┘ └──┘ └───────┘ └────┘
src ─┘ └────┘ └────┘┴ ┴ └─────┘ └──┘ └──┘┴ └───────┘┴ └────┘┴ └────
typ ─┘ └────┘ └────┘┴ ┴ └─────┘ └──┘ └──┘┴ └───────┘┴ └────┘┴ └────
doc ─┘ └────┘ ┴ ┴ └─────┘ └──┘ ┴ ┴ ┴ └────
txt ─┘ └────┘ ┴ ┴ └─────┘ └──┘ ┴ ┴ ┴ └────
par ─┘ └────┘ ┴ ┴ └─────┘ └──┘ ┴ ┴ ┴ └────
pid ─┘ └────┘ ┴ ┴ └─────┘ └──┘ ┴ ┴ ┴ └────
st ─────────────────────────────────────────────────────────────────
812 (some [])), from
id └┘
src ──┘ ┴└┘└───────┘
typ ──┘ ┴└┘└───────┘
doc ──┘ ┴ └───────┘
txt ──┘ ┴ └───────┘
par ──┘ ┴ └───────┘
pid ──┘ ┴ └───────┘
st ────────────────────
813 list_foldl' H
id └─────────┘
src └─────────┘┴ └
typ └─────────┘┴ └
doc ┴ └
txt ┴ └
par ┴ └
pid ┴ └
st ──────────────
814 ((list_reverse' H).comp (primrec.of_nat (list ℕ)))
id └───────────┘ └────────────┘ └──┘
src ─┘ └───────────┘┴ └─────┘ └────────────┘┴ └──┘┴ └───
typ ─┘ └───────────┘┴ └─────┘ └────────────┘┴ └──┘┴ └───
doc ─┘ ┴ └─────┘ ┴ ┴ └───
txt ─┘ ┴ └─────┘ ┴ ┴ └───
par ─┘ ┴ └─────┘ ┴ ┴ └───
pid ─┘ ┴ └─────┘ ┴ ┴ └───
st ─────────────────────────────────────────────────────
815 (const (some []))
id └───┘ └──┘
src ─┘ └───┘┴ └──┘┴ └──
typ ─┘ └───┘┴ └──┘┴ └──
doc ─┘ ┴ ┴ └──
txt ─┘ ┴ ┴ └──
par ─┘ ┴ ┴ └──
pid ─┘ ┴ ┴ └──
st ────────────────────
816 (primrec.comp₂ (bind_decode_iff.2 $ primrec₂.swap this) primrec₂.right),
id └───────────┘ └─────────────┘ └───────────┘ └────────────┘
src ─┘ └───────────┘┴ └─────────────┘└─┘ ┴└───────────┘┴ └┘└────────────┘└─┘
typ ─┘ └───────────┘┴ └─────────────┘└─┘ ┴└───────────┘┴ └┘└────────────┘└─┘
doc ─┘ ┴ └─┘ ┴ ┴ └┘ └─┘
txt ─┘ ┴ └─┘ ┴ ┴ └┘ └─┘
par ─┘ ┴ └─┘ ┴ ┴ └┘ └─┘
pid ─┘ ┴ └─┘ ┴ ┴ └┘ └─┘
st ───────────────────────────────────────────────────────────────────────────
817 nat_iff.1 $ (encode_iff.2 this).of_eq $ λ n, begin
id └─────┘ └────────┘
src └─────┘└─┘ ┴ └────────┘└─┘ └──────┘ ┴ └──┘ └
typ └─────┘└─┘ ┴ └────────┘└─┘ └──────┘ ┴ └──┘ └
doc └─┘ ┴ └─┘ └──────┘ ┴ └──┘ └
txt └─┘ ┴ └─┘ └──────┘ ┴ └──┘ └
par └─┘ ┴ └─┘ └──────┘ ┴ └──┘ └
pid └─┘ ┴ └─┘ └──────┘ ┴ └──┘ └
st ────────────────────────────────────────────┘└─────
818 rw list.foldl_reverse,
id └────────────────┘
src ─┘└─┘└────────────────┘└─
typ ─┘└─┘└────────────────┘└─
doc ─┘└─┘ └─
txt ─┘└─┘ └─
par ─┘└─┘ └─
pid ────┘ └─
st ──────────────────────┘└─
819 apply nat.case_strong_induction_on n, {refl},
id └──────────────────────────┘ ┴
src ─┘└────┘└──────────────────────────┘┴ └─┘└──┘└──
typ ───────┘└──────────────────────────┘┴┴└─┘└──┘└──
doc ─┘└────┘ ┴ └─┘└──┘└──
txt ─┘└────┘ ┴ └─┘└──┘└──
par ───────┘ ┴ └─┘└──┘└──
pid ───────┘ ┴ └─────────
st ─────────────────────────────────────┘└─────┘┴└─
820 intros n IH, simp,
src ─┘└─────────┘└┘└──┘└─
typ ─┘└─────────┘└┘└──┘└─
doc ─┘└─────────┘└┘└──┘└─
txt ─┘└─────────┘└┘└──┘└─
par ─┘└─────────┘└┘└──┘└─
pid ─────────────────────
st ────────────┘└────┘└─
821 cases decode α n.unpair.1 with a, {refl},
id └────┘ ┴ └──────┘
src ─┘└────┘└────┘┴ ┴└──────┘└───────┘└─┘└──┘└──
typ ─┘└────┘└────┘┴┴┴└──────┘└───────┘└─┘└──┘└──
doc ─┘└────┘ ┴ ┴└──────┘└───────┘└─┘└──┘└──
txt ─┘└────┘ ┴ ┴ └───────┘└─┘└──┘└──
par ─┘└────┘ ┴ ┴ └───────┘└─┘└──┘└──
pid ───────┘ ┴ ┴ └──────────────────
st ─────────────────────────────────┘└─────┘┴└─
822 simp,
src ─┘└──┘└─
typ ─┘└──┘└─
doc ─┘└──┘└─
txt ─┘└──┘└─
par ─┘└──┘└─
pid ────────
st ─────┘└─
823 suffices : ∀ (o : option (list ℕ)) p (_ : encode o = encode p),
id └────┘ └──┘ ┴
src ─┘└─────────┘ └────┘└────┘┴ └──┘┴ └────────┘ ┴ ┴┴┴ ┴ ┴ └
typ ─┘└─────────┘ └────┘└────┘┴ └──┘┴ └────────┘ ┴ ┴┴┴ ┴ ┴ └
doc ─┘└─────────┘ └────┘ ┴ ┴ └────────┘ ┴ ┴ ┴ ┴ ┴ └
txt ─┘└─────────┘ └────┘ ┴ ┴ └────────┘ ┴ ┴ ┴ ┴ ┴ └
par ─┘└─────────┘ └────┘ ┴ ┴ └────────┘ ┴ ┴ ┴ ┴ ┴ └
pid ────────────┘ └────┘ ┴ ┴ └────────┘ ┴ ┴ ┴ ┴ ┴ └
st ──────────────────────────────────────────────────────────────────
824 encode (option.map (list.cons (encode a)) o) =
src ───┘ ┴ ┴ ┴ ┴ └─┘ └┘ └
typ ───┘ ┴ ┴ ┴ ┴ └─┘ └┘ └
doc ───┘ ┴ ┴ ┴ ┴ └─┘ └┘ └
txt ───┘ ┴ ┴ ┴ ┴ └─┘ └┘ └
par ───┘ ┴ ┴ ┴ ┴ └─┘ └┘ └
pid ───┘ ┴ ┴ ┴ ┴ └─┘ └┘ └
st ───────────────────────────────────────────────────
825 encode (option.map (list.cons a) p),
id └────┘ └────────┘ └───────┘ ┴
src ───┘└────┘┴ └────────┘┴ └───────┘┴ └┘ ┴└─
typ ───┘└────┘┴ └────────┘┴ └───────┘┴┴└┘ ┴└─
doc ───┘ ┴ ┴ ┴ └┘ ┴└─
txt ───┘ ┴ ┴ ┴ └┘ ┴└─
par ───┘ ┴ ┴ ┴ └┘ ┴└─
pid ───┘ ┴ ┴ ┴ └┘ └──
st ──────────────────────────────────────┘└─
826 from this _ _ (IH _ (nat.unpair_le_right n)),
id └──┘ └┘ └─────────────────┘ ┴
src ─┘└───┘ └───┘ └─┘ └─────────────────┘┴ └┘└─
typ ──────┘└──┘└───┘ └┘└─┘ └─────────────────┘┴┴└───
doc ─┘└───┘ └───┘ └─┘ ┴ └┘└─
txt ─┘└───┘ └───┘ └─┘ ┴ └┘└─
par ──────┘ └───┘ └─┘ ┴ └───
pid ──────┘ └───┘ └─┘ ┴ └───
st ─────────────────────────────────────────────┘└─
827 intros o p IH,
src ─┘└───────────┘└─
typ ─┘└───────────┘└─
doc ─┘└───────────┘└─
txt ─┘└───────────┘└─
par ─┘└───────────┘└─
pid ─────────────────
st ──────────────┘└─
828 cases o; cases p; injection IH with h,
id ┴ ┴ └┘
src ─┘└────┘ └┘└────┘ └┘└────────┘ └─────┘└─
typ ─┘└────┘┴└┘└────┘┴└┘└────────┘└┘└─────┘└─
doc ─┘└────┘ └┘└────┘ └┘└────────┘ └─────┘└─
txt ─┘└────┘ └┘└────┘ └┘└────────┘ └─────┘└─
par ─┘└────┘ └┘└────┘ └┘└────────┘ └─────┘└─
pid ───────┘ └──────┘ └──────────┘ └────────
st ──────────────────────────────────────┘└─
829 exact congr_arg (λ k, (nat.mkpair (encode a) k).succ.succ) h
id └───────┘ └────────┘ └────┘ ┴ ┴
src ───────┘└───────┘┴ └──┘ └────────┘┴ └────┘┴ └┘ └───────────┘ └
typ ───────┘└───────┘┴ └──┘ └────────┘┴ └────┘┴┴└┘ └───────────┘┴└
doc ───────┘ ┴ └──┘ └────────┘┴ ┴ └┘ └───────────┘ └
txt ───────┘ ┴ └──┘ ┴ ┴ └┘ └───────────┘ └
par ───────┘ ┴ └──┘ ┴ ┴ └┘ └───────────┘ └
pid ───────┘ ┴ └──┘ ┴ ┴ └┘ └───────────┘ └
st ──────────────────────────────────────────────────────────────┘
830 end⟩
src ──┘
typ ──┘
doc ──┘
txt ──┘
par ──┘
pid ──┘
st └─┘
831
832 end primcodable
833
834 namespace primrec
835 variables {α : Type*} {β : Type*} {γ : Type*} {σ : Type*}
id ┴
typ ┴
836 variables [primcodable α] [primcodable β] [primcodable γ] [primcodable σ]
id └─────────┘ └─────────┘ └─────────┘ └─────────┘
src └─────────┘ └─────────┘ └─────────┘ └─────────┘
typ └─────────┘ └─────────┘ └─────────┘ └─────────┘
doc └─────────┘ └─────────┘ └─────────┘ └─────────┘
837
838 theorem sum_inl : primrec (@sum.inl α β) :=
id └─────┘ └─────┘ ┴ ┴
src └─────┘ └─────┘
typ └─────┘ └─────┘ ┴ ┴
doc └─────┘
839 encode_iff.1 $ nat_bit0.comp primrec.encode
id └────────┘┴ └──────┘└───┘ └────────────┘
src └────────┘┴ └──────┘└───┘ └────────────┘
typ └────────┘┴ └──────┘└───┘ └────────────┘
840
841 theorem sum_inr : primrec (@sum.inr α β) :=
id └─────┘ └─────┘ ┴ ┴
src └─────┘ └─────┘
typ └─────┘ └─────┘ ┴ ┴
doc └─────┘
842 encode_iff.1 $ nat_bit1.comp primrec.encode
id └────────┘┴ └──────┘└───┘ └────────────┘
src └────────┘┴ └──────┘└───┘ └────────────┘
typ └────────┘┴ └──────┘└───┘ └────────────┘
843
844 theorem sum_cases
845 {f : α → β ⊕ γ} {g : α → β → σ} {h : α → γ → σ}
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src ┴
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
846 (hf : primrec f) (hg : primrec₂ g) (hh : primrec₂ h) :
id └─────┘ ┴ └──────┘ ┴ └──────┘ ┴
src └─────┘ └──────┘ └──────┘
typ └─────┘ ┴ └──────┘ ┴ └──────┘ ┴
doc └─────┘ └──────┘ └──────┘
847 @primrec _ σ _ _ (λ a, sum.cases_on (f a) (g a) (h a)) :=
id └─────┘ ┴ ┴ └──────────┘ ┴ ┴ ┴ ┴ ┴ ┴
src └─────┘ └──────────┘
typ └─────┘ ┴ ┴ └──────────┘ ┴ ┴ ┴ ┴ ┴ ┴
doc └─────┘
848 option_some_iff.1 $
id └─────────────┘┴
src └─────────────┘┴
typ └─────────────┘┴
849 (cond (nat_bodd.comp $ encode_iff.2 hf)
id └──┘ └──────┘└───┘ └────────┘┴ └┘
src └──┘ └──────┘└───┘ └────────┘┴
typ └──┘ └──────┘└───┘ └────────┘┴ └┘
850 (option_map (primrec.decode.comp $ nat_div2.comp $ encode_iff.2 hf) hh)
id └────────┘ └────────────┘└───┘ └──────┘└───┘ └────────┘┴ └┘ └┘
src └────────┘ └────────────┘└───┘ └──────┘└───┘ └────────┘┴
typ └────────┘ └────────────┘└───┘ └──────┘└───┘ └────────┘┴ └┘ └┘
851 (option_map (primrec.decode.comp $ nat_div2.comp $ encode_iff.2 hf) hg)).of_eq $
id └────────┘ └────────────┘└───┘ └──────┘└───┘ └────────┘┴ └┘ └┘ └───┘
src └────────┘ └────────────┘└───┘ └──────┘└───┘ └────────┘┴ └───┘
typ └────────┘ └────────────┘└───┘ └──────┘└───┘ └────────┘┴ └┘ └┘ └───┘
852 λ a, by cases f a with b c;
id ┴ ┴ ┴
src └────┘ ┴ └───────┘
typ ┴ └────┘┴┴┴└───────┘
doc └────┘ ┴ └───────┘
txt └────┘ ┴ └───────┘
par └────┘ ┴ └───────┘
pid ┴ ┴ └───────┘
st └────────────────────
853 simp [nat.div2_bit, nat.bodd_bit, encodek]; refl
id └──────────┘ └──────────┘ └─────┘
src └────┘└──────────┘└┘└──────────┘└┘└─────┘┴ └────
typ └────┘└──────────┘└┘└──────────┘└┘└─────┘┴ └────
doc └────┘ └┘ └┘ ┴ └────
txt └────┘ └┘ └┘ ┴ └────
par └────┘ └┘ └┘ ┴ └────
pid ┴┴ └┘ └┘ ┴ └
st ───────────────────────────────────────────────────
854
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
855 theorem list_cons : primrec₂ (@list.cons α) :=
id └──────┘ └───────┘ ┴
src └──────┘ └───────┘
typ └──────┘ └───────┘ ┴
doc └──────┘
856 list_cons' (primcodable.prim _)
id └────────┘ └──────────────┘
src └────────┘ └──────────────┘
typ └────────┘ └──────────────┘
857
858 theorem list_cases
859 {f : α → list β} {g : α → σ} {h : α → β × list β → σ} :
id ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ ┴
src └──┘ ┴ └──┘
typ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ ┴
860 primrec f → primrec g → primrec₂ h →
id └─────┘ ┴ └─────┘ ┴ └──────┘ ┴
src └─────┘ └─────┘ └──────┘
typ └─────┘ ┴ └─────┘ ┴ └──────┘ ┴
doc └─────┘ └─────┘ └──────┘
861 @primrec _ σ _ _ (λ a, list.cases_on (f a) (g a) (λ b l, h a (b, l))) :=
id └─────┘ ┴ ┴ └───────────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴┴ ┴
src └─────┘ └───────────┘ ┴
typ └─────┘ ┴ ┴ └───────────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴┴ ┴
doc └─────┘
862 list_cases' (primcodable.prim _)
id └─────────┘ └──────────────┘
src └─────────┘ └──────────────┘
typ └─────────┘ └──────────────┘
863
864 theorem list_foldl
865 {f : α → list β} {g : α → σ} {h : α → σ × β → σ} :
id ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴
typ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
866 primrec f → primrec g → primrec₂ h →
id └─────┘ ┴ └─────┘ ┴ └──────┘ ┴
src └─────┘ └─────┘ └──────┘
typ └─────┘ ┴ └─────┘ ┴ └──────┘ ┴
doc └─────┘ └─────┘ └──────┘
867 primrec (λ a, (f a).foldl (λ s b, h a (s, b)) (g a)) :=
id └─────┘ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴ ┴
src └─────┘ └───┘ ┴
typ └─────┘ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴ ┴
doc └─────┘
868 list_foldl' (primcodable.prim _)
id └─────────┘ └──────────────┘
src └─────────┘ └──────────────┘
typ └─────────┘ └──────────────┘
869
870 theorem list_reverse : primrec (@list.reverse α) :=
id └─────┘ └──────────┘ ┴
src └─────┘ └──────────┘
typ └─────┘ └──────────┘ ┴
doc └─────┘
871 list_reverse' (primcodable.prim _)
id └───────────┘ └──────────────┘
src └───────────┘ └──────────────┘
typ └───────────┘ └──────────────┘
872
873 theorem list_foldr
874 {f : α → list β} {g : α → σ} {h : α → β × σ → σ}
id ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴
typ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
875 (hf : primrec f) (hg : primrec g) (hh : primrec₂ h) :
id └─────┘ ┴ └─────┘ ┴ └──────┘ ┴
src └─────┘ └─────┘ └──────┘
typ └─────┘ ┴ └─────┘ ┴ └──────┘ ┴
doc └─────┘ └─────┘ └──────┘
876 primrec (λ a, (f a).foldr (λ b s, h a (b, s)) (g a)) :=
id └─────┘ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴ ┴
src └─────┘ └───┘ ┴
typ └─────┘ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴ ┴
doc └─────┘
877 (list_foldl (list_reverse.comp hf) hg $ to₂ $
id └────────┘ └──────────┘└───┘ └┘ └┘ └─┘
src └────────┘ └──────────┘└───┘ └─┘
typ └────────┘ └──────────┘└───┘ └┘ └┘ └─┘
878 hh.comp fst $ (pair snd fst).comp snd).of_eq $
id └┘└───┘ └─┘ └──┘ └─┘ └─┘ └──┘ └─┘ └───┘
src └───┘ └─┘ └──┘ └─┘ └─┘ └──┘ └─┘ └───┘
typ └┘└───┘ └─┘ └──┘ └─┘ └─┘ └──┘ └─┘ └───┘
879 λ a, by simp [list.foldl_reverse]
id ┴ └────────────────┘
src └────┘└────────────────┘└─
typ ┴ └────┘└────────────────┘└─
doc └────┘ └─
txt └────┘ └─
par └────┘ └─
pid ┴┴ ┴└
st └──────────────────────────
880
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
881 theorem list_head' : primrec (@list.head' α) :=
id └─────┘ └────────┘ ┴
src └─────┘ └────────┘
typ └─────┘ └────────┘ ┴
doc └─────┘
882 (list_cases primrec.id (const none)
id └────────┘ └────────┘ └───┘ └──┘
src └────────┘ └────────┘ └───┘ └──┘
typ └────────┘ └────────┘ └───┘ └──┘
883 (option_some_iff.2 $ (fst.comp snd)).to₂).of_eq $
id └─────────────┘┴ └─┘└───┘ └─┘ └─┘ └───┘
src └─────────────┘┴ └─┘└───┘ └─┘ └─┘ └───┘
typ └─────────────┘┴ └─┘└───┘ └─┘ └─┘ └───┘
884 λ l, by cases l; refl
id ┴ ┴
src └────┘ └────
typ ┴ └────┘┴ └────
doc └────┘ └────
txt └────┘ └────
par └────┘ └────
pid ┴ └
st └──────────────
885
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
886 theorem list_head [inhabited α] : primrec (@list.head α _) :=
id └───────┘ ┴ └─────┘ └───────┘ ┴
src └───────┘ └─────┘ └───────┘
typ └───────┘ ┴ └─────┘ └───────┘ ┴
doc └─────┘
887 (option_iget.comp list_head').of_eq $
id └─────────┘└───┘ └────────┘ └───┘
src └─────────┘└───┘ └────────┘ └───┘
typ └─────────┘└───┘ └────────┘ └───┘
888 λ l, l.head_eq_head'.symm
id ┴ ┴└────────────┘└───┘
src └────────────┘└───┘
typ ┴ ┴└────────────┘└───┘
889
890 theorem list_tail : primrec (@list.tail α) :=
id └─────┘ └───────┘ ┴
src └─────┘ └───────┘
typ └─────┘ └───────┘ ┴
doc └─────┘
891 (list_cases primrec.id (const []) (snd.comp snd).to₂).of_eq $
id └────────┘ └────────┘ └───┘ └┘ └─┘└───┘ └─┘ └─┘ └───┘
src └────────┘ └────────┘ └───┘ └┘ └─┘└───┘ └─┘ └─┘ └───┘
typ └────────┘ └────────┘ └───┘ └┘ └─┘└───┘ └─┘ └─┘ └───┘
892 λ l, by cases l; refl
id ┴ ┴
src └────┘ └────
typ ┴ └────┘┴ └────
doc └────┘ └────
txt └────┘ └────
par └────┘ └────
pid ┴ └
st └──────────────
893
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
894 theorem list_rec
895 {f : α → list β} {g : α → σ} {h : α → β × list β × σ → σ}
id ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴
src └──┘ ┴ └──┘ ┴
typ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴
896 (hf : primrec f) (hg : primrec g) (hh : primrec₂ h) :
id └─────┘ ┴ └─────┘ ┴ └──────┘ ┴
src └─────┘ └─────┘ └──────┘
typ └─────┘ ┴ └─────┘ ┴ └──────┘ ┴
doc └─────┘ └─────┘ └──────┘
897 @primrec _ σ _ _ (λ a,
id └─────┘ ┴ ┴
src └─────┘
typ └─────┘ ┴ ┴
doc └─────┘
898 list.rec_on (f a) (g a) (λ b l IH, h a (b, l, IH))) :=
id └─────────┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴┴ ┴ └┘
src └─────────┘ ┴
typ └─────────┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴┴ ┴ └┘
899 let F (a : α) := (f a).foldr
id ┴ ┴ ┴ ┴ └───┘
src └───┘
typ ┴ ┴ ┴ ┴ └───┘
900 (λ (b : β) (s : list β × σ), (b :: s.1, h a (b, s))) ([], g a) in
id ┴ └──┘ ┴ ┴ ┴ ┴┴ └┘ ┴┴ ┴ ┴ ┴┴ ┴ ┴└┘ ┴ ┴
src └──┘ ┴ ┴ └┘ ┴ ┴ ┴└┘
typ ┴ └──┘ ┴ ┴ ┴ ┴┴ └┘ ┴┴ ┴ ┴ ┴┴ ┴ ┴└┘ ┴ ┴
901 have primrec F, from
id └─────┘ ┴
src └─────┘
typ └─────┘ ┴
doc └─────┘
902 list_foldr hf (pair (const []) hg) $ to₂ $
id └────────┘ └┘ └──┘ └───┘ └┘ └┘ └─┘
src └────────┘ └──┘ └───┘ └┘ └─┘
typ └────────┘ └┘ └──┘ └───┘ └┘ └┘ └─┘
903 pair ((list_cons.comp fst (fst.comp snd)).comp snd) hh,
id └──┘ └───────┘└───┘ └─┘ └─┘└───┘ └─┘ └──┘ └─┘ └┘
src └──┘ └───────┘└───┘ └─┘ └─┘└───┘ └─┘ └──┘ └─┘
typ └──┘ └───────┘└───┘ └─┘ └─┘└───┘ └─┘ └──┘ └─┘ └┘
904 (snd.comp this).of_eq $ λ a, begin
id └─┘└───┘ └──┘ └───┘ ┴
src └─┘└───┘ └───┘
typ └─┘└───┘ └──┘ └───┘ ┴
st └─────
905 suffices : F a = (f a,
id ┴ ┴
src └─────────┘ ┴ ┴┴┴ ┴ └─
typ └─────────┘┴┴ ┴┴┴ ┴ └─
doc └─────────┘ ┴ ┴ ┴ ┴ └─
txt └─────────┘ ┴ ┴ ┴ ┴ └─
par └─────────┘ ┴ ┴ ┴ ┴ └─
pid └───────┘└┘ ┴ ┴ ┴ ┴ └─
st ─────────────────────────
906 list.rec_on (f a) (g a) (λ b l IH, h a (b, l, IH))), {rw this},
id └─────────┘ ┴ ┴ ┴ ┴ ┴ └──┘
src ───┘└─────────┘┴ ┴ └┘ ┴ └┘ └───────┘ ┴ ┴┴ └┘ └┘ └─┘ └─┘
typ ───┘└─────────┘┴ ┴┴ └┘ ┴┴ └┘ └───────┘┴┴┴┴┴ └┘ └┘ └─┘ └─┘└──┘
doc ───┘ ┴ ┴ └┘ ┴ └┘ └───────┘ ┴ ┴ └┘ └┘ └─┘ └─┘
txt ───┘ ┴ ┴ └┘ ┴ └┘ └───────┘ ┴ ┴ └┘ └┘ └─┘ └─┘
par ───┘ ┴ ┴ └┘ ┴ └┘ └───────┘ ┴ ┴ └┘ └┘ └─┘ └─┘
pid ───┘ ┴ ┴ └┘ ┴ └┘ └───────┘ ┴ ┴ └┘ └┘ └─┘ ┴
st ──────────────────────────────────────────────────────┘└────┘└──┘└┘└
907 simp [F], induction f a with b l IH; simp *
id ┴ ┴ ┴
src └────┘ ┴ └────────┘ ┴ └──────────┘ └─────┘
typ └────┘┴┴ └────────┘┴┴┴└──────────┘ └─────┘
doc └────┘ ┴ └────────┘ ┴ └──────────┘ └─────┘
txt └────┘ ┴ └────────┘ ┴ └──────────┘ └─────┘
par └────┘ ┴ └────────┘ ┴ └──────────┘ └─────┘
pid ┴┴ ┴ ┴ ┴ ┴└─────────┘ ┴┴┴
st ─────────┘└──────────────────────────────────┘
908 end
st └─┘
909
910 theorem list_nth : primrec₂ (@list.nth α) :=
id └──────┘ └──────┘ ┴
src └──────┘ └──────┘
typ └──────┘ └──────┘ ┴
doc └──────┘
911 let F (l : list α) (n : ℕ) :=
id ┴ └──┘ ┴ ┴
src └──┘ ┴
typ ┴ └──┘ ┴ ┴
912 l.foldl (λ (s : ℕ ⊕ α) (a : α),
id ┴└────┘ ┴ ┴ ┴ ┴
src └────┘ ┴ ┴
typ ┴└────┘ ┴ ┴ ┴ ┴
913 sum.cases_on s
id └──────────┘ ┴
src └──────────┘
typ └──────────┘ ┴
914 (@nat.cases (ℕ ⊕ α) (sum.inr a) sum.inl) sum.inr)
id └───────┘ ┴ ┴ ┴ └─────┘ ┴ └─────┘ └─────┘
src └───────┘ ┴ ┴ └─────┘ └─────┘ └─────┘
typ └───────┘ ┴ ┴ ┴ └─────┘ ┴ └─────┘ └─────┘
915 (sum.inl n) in
id └─────┘ ┴
src └─────┘
typ └─────┘ ┴
916 have hF : primrec₂ F, from
id └──────┘ ┴
src └──────┘
typ └──────┘ ┴
doc └──────┘
917 list_foldl fst (sum_inl.comp snd) ((sum_cases fst
id └────────┘ └─┘ └─────┘└───┘ └─┘ └───────┘ └─┘
src └────────┘ └─┘ └─────┘└───┘ └─┘ └───────┘ └─┘
typ └────────┘ └─┘ └─────┘└───┘ └─┘ └───────┘ └─┘
918 (nat_cases snd
id └───────┘ └─┘
src └───────┘ └─┘
typ └───────┘ └─┘
919 (sum_inr.comp $ snd.comp fst)
id └─────┘└───┘ └─┘└───┘ └─┘
src └─────┘└───┘ └─┘└───┘ └─┘
typ └─────┘└───┘ └─┘└───┘ └─┘
920 (sum_inl.comp snd).to₂).to₂
id └─────┘└───┘ └─┘ └─┘ └─┘
src └─────┘└───┘ └─┘ └─┘ └─┘
typ └─────┘└───┘ └─┘ └─┘ └─┘
921 (sum_inr.comp snd).to₂).comp snd).to₂,
id └─────┘└───┘ └─┘ └─┘ └──┘ └─┘ └─┘
src └─────┘└───┘ └─┘ └─┘ └──┘ └─┘ └─┘
typ └─────┘└───┘ └─┘ └─┘ └──┘ └─┘ └─┘
922 have @primrec _ (option α) _ _ (λ p : list α × ℕ,
id └─────┘ └────┘ ┴ └──┘ ┴ ┴ ┴
src └─────┘ └────┘ └──┘ ┴ ┴
typ └─────┘ └────┘ ┴ └──┘ ┴ ┴ ┴
doc └─────┘
923 sum.cases_on (F p.1 p.2) (λ _, none) some), from
id └──────────┘ ┴ ┴┴ ┴┴ ┴ └──┘ └──┘
src └──────────┘ ┴ ┴ └──┘ └──┘
typ └──────────┘ ┴ ┴┴ ┴┴ ┴ └──┘ └──┘
924 sum_cases hF (const none).to₂ (option_some.comp snd).to₂,
id └───────┘ └┘ └───┘ └──┘ └─┘ └─────────┘└───┘ └─┘ └─┘
src └───────┘ └───┘ └──┘ └─┘ └─────────┘└───┘ └─┘ └─┘
typ └───────┘ └┘ └───┘ └──┘ └─┘ └─────────┘└───┘ └─┘ └─┘
925 this.to₂.of_eq $ λ l n, begin
id └──┘└──┘└────┘ ┴ ┴
src └──┘└────┘
typ └──┘└──┘└────┘ ┴ ┴
st └─────
926 dsimp, symmetry,
src └───┘ └──────┘
typ └───┘ └──────┘
doc └───┘ └──────┘
txt └───┘ └──────┘
par └───┘ └──────┘
st ──────┘└────────┘└─
927 induction l with a l IH generalizing n, {refl},
id ┴
src └────────┘ └─────────────────────────┘ └──┘
typ └────────┘┴└─────────────────────────┘ └──┘
doc └────────┘ └─────────────────────────┘ └──┘
txt └────────┘ └─────────────────────────┘ └──┘
par └────────┘ └─────────────────────────┘ └──┘
pid ┴ ┴└─────────┘└─────────────┘
st ───────────────────────────────────────┘└─────┘└┘└
928 cases n with n,
id ┴
src └────┘ └─────┘
typ └────┘┴└─────┘
doc └────┘ └─────┘
txt └────┘ └─────┘
par └────┘ └─────┘
pid ┴ └─────┘
st ───────────────┘└─
929 { rw [(_ : F (a :: l) 0 = sum.inr a)], {refl},
id ┴ ┴ ┴ └─────┘ ┴
src └──┘ └──┘ ┴ ┴ ┴ └──┘┴┴└─────┘┴ └┘ └──┘
typ └──┘ └──┘┴┴ ┴ ┴┴└──┘┴┴└─────┘┴┴└┘ └──┘
doc └──┘ └──┘ ┴ ┴ ┴ └──┘ ┴ ┴ └┘ └──┘
txt └──┘ └──┘ ┴ ┴ ┴ └──┘ ┴ ┴ └┘ └──┘
par └──┘ └──┘ ┴ ┴ ┴ └──┘ ┴ ┴ └┘ └──┘
pid └┘ └──┘ ┴ ┴ ┴ └──┘ ┴ ┴ └┘
st ───┘└────────────────────────────────┘┴└─────┘└┘└
930 clear IH, dsimp [F],
id ┴
src └──────┘ └─────┘ ┴
typ └──────┘ └─────┘┴┴
doc └──────┘ └─────┘ ┴
txt └──────┘ └─────┘ ┴
par └──────┘ └─────┘ ┴
pid └─┘ ┴┴ ┴
st ───────────┘└─────────┘└─
931 induction l with b l IH; simp * },
id ┴
src └────────┘ └──────────┘ └─────┘
typ └────────┘┴└──────────┘ └─────┘
doc └────────┘ └──────────┘ └─────┘
txt └────────┘ └──────────┘ └─────┘
par └────────┘ └──────────┘ └─────┘
pid ┴ ┴└─────────┘ ┴┴┴
st ───────────────────────────────────┘└┘└
932 { apply IH }
src └────┘ ┴
typ └────┘ ┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴ ┴
st ────────────┘└─
933 end
st ──┘
934
935 theorem list_inth [inhabited α] : primrec₂ (@list.inth α _) :=
id └───────┘ ┴ └──────┘ └───────┘ ┴
src └───────┘ └──────┘ └───────┘
typ └───────┘ ┴ └──────┘ └───────┘ ┴
doc └──────┘ └───────┘
936 option_iget.comp₂ list_nth
id └─────────┘└────┘ └──────┘
src └─────────┘└────┘ └──────┘
typ └─────────┘└────┘ └──────┘
937
938 theorem list_append : primrec₂ ((++) : list α → list α → list α) :=
id └──────┘ ┴ └──┘ ┴ └──┘ ┴ └──┘ ┴
src └──────┘ ┴ └──┘ └──┘ └──┘
typ └──────┘ ┴ └──┘ ┴ └──┘ ┴ └──┘ ┴
doc └──────┘
939 (list_foldr fst snd $ to₂ $ comp (@list_cons α _) snd).to₂.of_eq $
id └────────┘ └─┘ └─┘ └─┘ └──┘ └───────┘ ┴ └─┘ └─┘ └───┘
src └────────┘ └─┘ └─┘ └─┘ └──┘ └───────┘ └─┘ └─┘ └───┘
typ └────────┘ └─┘ └─┘ └─┘ └──┘ └───────┘ ┴ └─┘ └─┘ └───┘
940 λ l₁ l₂, by induction l₁; simp *
id └┘ └┘ └┘
src └────────┘ └──────
typ └┘ └┘ └────────┘└┘ └──────
doc └────────┘ └──────
txt └────────┘ └──────
par └────────┘ └──────
pid ┴ ┴┴└
st └─────────────────────
941
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
942 theorem list_concat : primrec₂ (λ l (a:α), l ++ [a]) :=
id └──────┘ ┴ ┴ ┴ └┘ ┴┴┴
src └──────┘ └┘ ┴ ┴
typ └──────┘ ┴ ┴ ┴ └┘ ┴┴┴
doc └──────┘
943 list_append.comp fst (list_cons.comp snd (const []))
id └─────────┘└───┘ └─┘ └───────┘└───┘ └─┘ └───┘ └┘
src └─────────┘└───┘ └─┘ └───────┘└───┘ └─┘ └───┘ └┘
typ └─────────┘└───┘ └─┘ └───────┘└───┘ └─┘ └───┘ └┘
944
945 theorem list_map
946 {f : α → list β} {g : α → β → σ}
id ┴ └──┘ ┴ ┴ ┴ ┴
src └──┘
typ ┴ └──┘ ┴ ┴ ┴ ┴
947 (hf : primrec f) (hg : primrec₂ g) :
id └─────┘ ┴ └──────┘ ┴
src └─────┘ └──────┘
typ └─────┘ ┴ └──────┘ ┴
doc └─────┘ └──────┘
948 primrec (λ a, (f a).map (g a)) :=
id └─────┘ ┴ ┴ ┴ └─┘ ┴ ┴
src └─────┘ └─┘
typ └─────┘ ┴ ┴ ┴ └─┘ ┴ ┴
doc └─────┘
949 (list_foldr hf (const []) $ to₂ $ list_cons.comp
id └────────┘ └┘ └───┘ └┘ └─┘ └───────┘└───┘
src └────────┘ └───┘ └┘ └─┘ └───────┘└───┘
typ └────────┘ └┘ └───┘ └┘ └─┘ └───────┘└───┘
950 (hg.comp fst (fst.comp snd)) (snd.comp snd)).of_eq $
id └┘└───┘ └─┘ └─┘└───┘ └─┘ └─┘└───┘ └─┘ └───┘
src └───┘ └─┘ └─┘└───┘ └─┘ └─┘└───┘ └─┘ └───┘
typ └┘└───┘ └─┘ └─┘└───┘ └─┘ └─┘└───┘ └─┘ └───┘
951 λ a, by induction f a; simp *
id ┴ ┴ ┴
src └────────┘ ┴ └──────
typ ┴ └────────┘┴┴┴ └──────
doc └────────┘ ┴ └──────
txt └────────┘ ┴ └──────
par └────────┘ ┴ └──────
pid ┴ ┴ ┴┴└
st └──────────────────────
952
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
953 theorem list_range : primrec list.range :=
id └─────┘ └────────┘
src └─────┘ └────────┘
typ └─────┘ └────────┘
doc └─────┘
954 (nat_elim' primrec.id (const [])
id └───────┘ └────────┘ └───┘ └┘
src └───────┘ └────────┘ └───┘ └┘
typ └───────┘ └────────┘ └───┘ └┘
955 ((list_concat.comp snd fst).comp snd).to₂).of_eq $
id └─────────┘└───┘ └─┘ └─┘ └──┘ └─┘ └─┘ └───┘
src └─────────┘└───┘ └─┘ └─┘ └──┘ └─┘ └─┘ └───┘
typ └─────────┘└───┘ └─┘ └─┘ └──┘ └─┘ └─┘ └───┘
956 λ n, by simp; induction n; simp [*, list.range_concat]; refl
id ┴ ┴ └───────────────┘
src └──┘ └────────┘ └───────┘└───────────────┘┴ └────
typ ┴ └──┘ └────────┘┴ └───────┘└───────────────┘┴ └────
doc └──┘ └────────┘ └───────┘ ┴ └────
txt └──┘ └────────┘ └───────┘ ┴ └────
par └──┘ └────────┘ └───────┘ ┴ └────
pid ┴ ┴└──┘ ┴ └
st └─────────────────────────────────────────────────────
957
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
958 theorem list_join : primrec (@list.join α) :=
id └─────┘ └───────┘ ┴
src └─────┘ └───────┘
typ └─────┘ └───────┘ ┴
doc └─────┘
959 (list_foldr primrec.id (const []) $ to₂ $
id └────────┘ └────────┘ └───┘ └┘ └─┘
src └────────┘ └────────┘ └───┘ └┘ └─┘
typ └────────┘ └────────┘ └───┘ └┘ └─┘
960 comp (@list_append α _) snd).of_eq $
id └──┘ └─────────┘ ┴ └─┘ └───┘
src └──┘ └─────────┘ └─┘ └───┘
typ └──┘ └─────────┘ ┴ └─┘ └───┘
961 λ l, by dsimp; induction l; simp *
id ┴ ┴
src └───┘ └────────┘ └──────
typ ┴ └───┘ └────────┘┴ └──────
doc └───┘ └────────┘ └──────
txt └───┘ └────────┘ └──────
par └───┘ └────────┘ └──────
pid ┴ ┴┴└
st └───────────────────────────
962
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
963 theorem list_length : primrec (@list.length α) :=
id └─────┘ └─────────┘ ┴
src └─────┘ └─────────┘
typ └─────┘ └─────────┘ ┴
doc └─────┘
964 (list_foldr (@primrec.id (list α) _) (const 0) $ to₂ $
id └────────┘ └────────┘ └──┘ ┴ └───┘ └─┘
src └────────┘ └────────┘ └──┘ └───┘ └─┘
typ └────────┘ └────────┘ └──┘ ┴ └───┘ └─┘
965 (succ.comp $ snd.comp snd).to₂).of_eq $
id └──┘└───┘ └─┘└───┘ └─┘ └─┘ └───┘
src └──┘└───┘ └─┘└───┘ └─┘ └─┘ └───┘
typ └──┘└───┘ └─┘└───┘ └─┘ └─┘ └───┘
966 λ l, by dsimp; induction l; simp [*, -add_comm]
id ┴ ┴
src └───┘ └────────┘ └───────────────────
typ ┴ └───┘ └────────┘┴ └───────────────────
doc └───┘ └────────┘ └───────────────────
txt └───┘ └────────┘ └───────────────────
par └───┘ └────────┘ └───────────────────
pid ┴ ┴└────────────┘└
st └────────────────────────────────────────
967
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
968 theorem list_find_index {f : α → list β} {p : α → β → Prop}
id ┴ └──┘ ┴ ┴ ┴
src └──┘
typ ┴ └──┘ ┴ ┴ ┴
969 [∀ a b, decidable (p a b)]
id ┴ ┴ └───────┘ ┴ ┴ ┴
src └───────┘
typ ┴ ┴ └───────┘ ┴ ┴ ┴
970 (hf : primrec f) (hp : primrec_rel p) :
id └─────┘ ┴ └─────────┘ ┴
src └─────┘ └─────────┘
typ └─────┘ ┴ └─────────┘ ┴
doc └─────┘ └─────────┘
971 primrec (λ a, (f a).find_index (p a)) :=
id └─────┘ ┴ ┴ ┴ └────────┘ ┴ ┴
src └─────┘ └────────┘
typ └─────┘ ┴ ┴ ┴ └────────┘ ┴ ┴
doc └─────┘
972 (list_foldr hf (const 0) $ to₂ $
id └────────┘ └┘ └───┘ └─┘
src └────────┘ └───┘ └─┘
typ └────────┘ └┘ └───┘ └─┘
973 ite (hp.comp fst $ fst.comp snd) (const 0)
id └─┘ └┘└───┘ └─┘ └─┘└───┘ └─┘ └───┘
src └─┘ └───┘ └─┘ └─┘└───┘ └─┘ └───┘
typ └─┘ └┘└───┘ └─┘ └─┘└───┘ └─┘ └───┘
974 (succ.comp $ snd.comp snd)).of_eq $
id └──┘└───┘ └─┘└───┘ └─┘ └───┘
src └──┘└───┘ └─┘└───┘ └─┘ └───┘
typ └──┘└───┘ └─┘└───┘ └─┘ └───┘
975 λ a, eq.symm $ by dsimp; induction f a with b l;
id ┴ └─────┘ ┴ ┴
src └─────┘ └───┘ └────────┘ ┴ └───────┘
typ ┴ └─────┘ └───┘ └────────┘┴┴┴└───────┘
doc └───┘ └────────┘ ┴ └───────┘
txt └───┘ └────────┘ ┴ └───────┘
par └───┘ └────────┘ ┴ └───────┘
pid ┴ ┴ ┴└──────┘
st └───────────────────────────────
976 [refl, { simp [*, list.find_index], congr }]
id ┴ └─────────────┘
src ┴└──┘ └───────┘└─────────────┘┴ └────┘
typ ┴└──┘ └───────┘└─────────────┘┴ └────┘
doc └──┘ └───────┘ ┴
txt └──┘ └───────┘ ┴ └────┘
par └──┘ └───────┘ ┴ └────┘
pid ┴└──┘ ┴ ┴
st ────────┘└─────────────────────────┘└──────┘└┘
977
978 theorem list_index_of [decidable_eq α] : primrec₂ (@list.index_of α _) :=
id └──────────┘ ┴ └──────┘ └───────────┘ ┴
src └──────────┘ └──────┘ └───────────┘
typ └──────────┘ ┴ └──────┘ └───────────┘ ┴
doc └──────┘
979 to₂ $ list_find_index snd $ primrec.eq.comp₂ (fst.comp fst).to₂ snd.to₂
id └─┘ └─────────────┘ └─┘ └────────┘└────┘ └─┘└───┘ └─┘ └─┘ └─┘└──┘
src └─┘ └─────────────┘ └─┘ └────────┘└────┘ └─┘└───┘ └─┘ └─┘ └─┘└──┘
typ └─┘ └─────────────┘ └─┘ └────────┘└────┘ └─┘└───┘ └─┘ └─┘ └─┘└──┘
980
981 theorem nat_strong_rec
982 (f : α → ℕ → σ) {g : α → list σ → option σ} (hg : primrec₂ g)
id ┴ ┴ ┴ ┴ └──┘ ┴ └────┘ ┴ └──────┘ ┴
src ┴ └──┘ └────┘ └──────┘
typ ┴ ┴ ┴ ┴ └──┘ ┴ └────┘ ┴ └──────┘ ┴
doc └──────┘
983 (H : ∀ a n, g a ((list.range n).map (f a)) = some (f a n)) : primrec₂ f :=
id ┴ ┴ ┴ ┴ └────────┘ ┴ └─┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ └──────┘ ┴
src └────────┘ └─┘ ┴ └──┘ └──────┘
typ ┴ ┴ ┴ ┴ └────────┘ ┴ └─┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ └──────┘ ┴
doc └──────┘
984 suffices primrec₂ (λ a n, (list.range n).map (f a)), from
id └──────┘ ┴ ┴ └────────┘ ┴ └─┘ ┴ ┴
src └──────┘ └────────┘ └─┘
typ └──────┘ ┴ ┴ └────────┘ ┴ └─┘ ┴ ┴
doc └──────┘
985 primrec₂.option_some_iff.1 $
id └──────────────────────┘┴
src └──────────────────────┘┴
typ └──────────────────────┘┴
986 (list_nth.comp (this.comp fst (succ.comp snd)) snd).to₂.of_eq $
id └──────┘└───┘ └──┘└───┘ └─┘ └──┘└───┘ └─┘ └─┘ └─┘ └───┘
src └──────┘└───┘ └───┘ └─┘ └──┘└───┘ └─┘ └─┘ └─┘ └───┘
typ └──────┘└───┘ └──┘└───┘ └─┘ └──┘└───┘ └─┘ └─┘ └─┘ └───┘
987 λ a n, by simp [list.nth_range (nat.lt_succ_self n)]; refl,
id ┴ ┴ └────────────┘ └──────────────┘ ┴
src └────┘└────────────┘┴ └──────────────┘┴ └┘ └──┘
typ ┴ ┴ └────┘└────────────┘┴ └──────────────┘┴┴└┘ └──┘
doc └────┘ ┴ ┴ └┘ └──┘
txt └────┘ ┴ ┴ └┘ └──┘
par └────┘ ┴ ┴ └┘ └──┘
pid ┴┴ ┴ ┴ └┘
st └───────────────────────────────────────────────┘
988 primrec₂.option_some_iff.1 $
id └──────────────────────┘┴
src └──────────────────────┘┴
typ └──────────────────────┘┴
989 (nat_elim (const (some [])) (to₂ $
id └──────┘ └───┘ └──┘ └┘ └─┘
src └──────┘ └───┘ └──┘ └┘ └─┘
typ └──────┘ └───┘ └──┘ └┘ └─┘
990 option_bind (snd.comp snd) $ to₂ $
id └─────────┘ └─┘└───┘ └─┘ └─┘
src └─────────┘ └─┘└───┘ └─┘ └─┘
typ └─────────┘ └─┘└───┘ └─┘ └─┘
991 option_map
id └────────┘
src └────────┘
typ └────────┘
992 (hg.comp (fst.comp fst) snd)
id └┘└───┘ └─┘└───┘ └─┘ └─┘
src └───┘ └─┘└───┘ └─┘ └─┘
typ └┘└───┘ └─┘└───┘ └─┘ └─┘
993 (to₂ $ list_concat.comp (snd.comp fst) snd))).of_eq $
id └─┘ └─────────┘└───┘ └─┘└───┘ └─┘ └─┘ └───┘
src └─┘ └─────────┘└───┘ └─┘└───┘ └─┘ └─┘ └───┘
typ └─┘ └─────────┘└───┘ └─┘└───┘ └─┘ └─┘ └───┘
994 λ a n, begin
id ┴ ┴
typ ┴ ┴
st └─────
995 simp, induction n with n IH, {refl},
id ┴
src └──┘ └────────┘ └────────┘ └──┘
typ └──┘ └────────┘┴└────────┘ └──┘
doc └──┘ └────────┘ └────────┘ └──┘
txt └──┘ └────────┘ └────────┘ └──┘
par └──┘ └────────┘ └────────┘ └──┘
pid ┴ ┴└───────┘
st ─────┘└─────────────────────┘└─────┘└┘└
996 simp [IH, H, list.range_concat]
id └┘ ┴ └───────────────┘
src └────┘ └┘ └┘└───────────────┘└┘
typ └────┘└┘└┘┴└┘└───────────────┘└┘
doc └────┘ └┘ └┘ └┘
txt └────┘ └┘ └┘ └┘
par └────┘ └┘ └┘ └┘
pid ┴┴ └┘ └┘ ┴┴
st ─────────────────────────────────┘
997 end
st └─┘
998
999 end primrec
1000
1001 namespace primcodable
1002 variables {α : Type*} {β : Type*}
1003 variables [primcodable α] [primcodable β]
id └─────────┘ └─────────┘
src └─────────┘ └─────────┘
typ └─────────┘ └─────────┘
doc └─────────┘ └─────────┘
1004 open primrec
1005
1006 def subtype {p : α → Prop} [decidable_pred p]
id ┴ └────────────┘ ┴
src └────────────┘
typ ┴ └────────────┘ ┴
1007 (hp : primrec_pred p) : primcodable (subtype p) :=
id └──────────┘ ┴ └─────────┘ └─────┘ ┴
src └──────────┘ └─────────┘ └─────┘
typ └──────────┘ ┴ └─────────┘ └─────┘ ┴
doc └──────────┘ └─────────┘
1008 ⟨have primrec (λ n, (decode α n).bind (λ a, option.guard p a)),
id └─────┘ ┴ └────┘ ┴ ┴ └──┘ ┴ └──────────┘ ┴ ┴
src └─────┘ └────┘ └──┘ └──────────┘
typ └─────┘ ┴ └────┘ ┴ ┴ └──┘ ┴ └──────────┘ ┴ ┴
doc └─────┘ └──────────┘
1009 from option_bind primrec.decode (option_guard (hp.comp snd) snd),
id └─────────┘ └────────────┘ └──────────┘ └┘└───┘ └─┘ └─┘
src └─────────┘ └────────────┘ └──────────┘ └───┘ └─┘ └─┘
typ └─────────┘ └────────────┘ └──────────┘ └┘└───┘ └─┘ └─┘
1010 nat_iff.1 $ (encode_iff.2 this).of_eq $ λ n,
id └─────┘┴ └────────┘┴ └──┘ └───┘ ┴
src └─────┘┴ └────────┘┴ └───┘ ┴
typ └─────┘┴ └────────┘┴ └──┘ └───┘ ┴
1011 show _ = encode ((decode α n).bind (λ a, _)), begin
id ┴ └────┘ └────┘ ┴ ┴ └──┘ ┴
src ┴ └────┘ └────┘ └──┘
typ ┴ └────┘ └────┘ ┴ ┴ └──┘ ┴
st └─────
1012 cases decode α n with a, {refl},
id └────┘ ┴ ┴
src └────┘└────┘┴ ┴ └─────┘ └──┘
typ └────┘└────┘┴┴┴┴└─────┘ └──┘
doc └────┘ ┴ ┴ └─────┘ └──┘
txt └────┘ ┴ ┴ └─────┘ └──┘
par └────┘ ┴ ┴ └─────┘ └──┘
pid ┴ ┴ ┴ └─────┘
st ─────────────────────────┘└─────┘└┘└
1013 dsimp [option.guard],
id └──────────┘
src └─────┘└──────────┘┴
typ └─────┘└──────────┘┴
doc └─────┘└──────────┘┴
txt └─────┘ ┴
par └─────┘ ┴
pid ┴┴ ┴
st ──────────────────────┘└─
1014 by_cases h : p a; simp [h]; refl
id ┴ ┴ ┴
src └───────┘ └─┘ ┴ └────┘ ┴ └────
typ └───────┘ └─┘┴┴┴ └────┘┴┴ └────
doc └───────┘ └─┘ ┴ └────┘ ┴ └────
txt └───────┘ └─┘ ┴ └────┘ ┴ └────
par └───────┘ └─┘ ┴ └────┘ ┴ └────
pid ┴ └─┘ ┴ ┴┴ ┴ └
st ────────────────────────────────────
1015 end⟩
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘└─┘
1016
1017 instance fin {n} : primcodable (fin n) :=
id └─────────┘ └─┘ ┴
src └─────────┘ └─┘
typ └─────────┘ └─┘ ┴
doc └─────────┘
1018 @of_equiv _ _
id └──────┘
src └──────┘
typ └──────┘
1019 (subtype $ nat_lt.comp primrec.id (const n))
id └─────┘ └────┘└───┘ └────────┘ └───┘ ┴
src └─────┘ └────┘└───┘ └────────┘ └───┘
typ └─────┘ └────┘└───┘ └────────┘ └───┘ ┴
1020 (equiv.fin_equiv_subtype _)
id └─────────────────────┘
src └─────────────────────┘
typ └─────────────────────┘
1021
1022 instance vector {n} : primcodable (vector α n) :=
id └─────────┘ └────┘ ┴ ┴
src └─────────┘ └────┘
typ └─────────┘ └────┘ ┴ ┴
doc └─────────┘
1023 subtype ((@primrec.eq _ _ nat.decidable_eq).comp list_length (const _))
id └─────┘ └────────┘ └──────────────┘ └──┘ └─────────┘ └───┘
src └─────┘ └────────┘ └──────────────┘ └──┘ └─────────┘ └───┘
typ └─────┘ └────────┘ └──────────────┘ └──┘ └─────────┘ └───┘
1024
1025 instance fin_arrow {n} : primcodable (fin n → α) :=
id └─────────┘ └─┘ ┴ ┴
src └─────────┘ └─┘
typ └─────────┘ └─┘ ┴ ┴
doc └─────────┘
1026 of_equiv _ (equiv.vector_equiv_fin _ _).symm
id └──────┘ └────────────────────┘ └──┘
src └──────┘ └────────────────────┘ └──┘
typ └──────┘ └────────────────────┘ └──┘
1027
1028 instance array {n} : primcodable (array n α) :=
id └─────────┘ └───┘ ┴ ┴
src └─────────┘ └───┘
typ └─────────┘ └───┘ ┴ ┴
doc └─────────┘
1029 of_equiv _ (equiv.array_equiv_fin _ _)
id └──────┘ └───────────────────┘
src └──────┘ └───────────────────┘
typ └──────┘ └───────────────────┘
1030
1031 end primcodable
1032
1033 namespace primrec
1034 variables {α : Type*} {β : Type*} {γ : Type*} {σ : Type*}
id ┴
typ ┴
1035 variables [primcodable α] [primcodable β] [primcodable γ] [primcodable σ]
id └─────────┘ └─────────┘ └─────────┘ └─────────┘
src └─────────┘ └─────────┘ └─────────┘ └─────────┘
typ └─────────┘ └─────────┘ └─────────┘ └─────────┘
doc └─────────┘ └─────────┘ └─────────┘ └─────────┘
1036
1037 theorem subtype_val {p : α → Prop} [decidable_pred p]
id ┴ └────────────┘ ┴
src └────────────┘
typ ┴ └────────────┘ ┴
1038 {hp : primrec_pred p} :
id └──────────┘ ┴
src └──────────┘
typ └──────────┘ ┴
doc └──────────┘
1039 by haveI := primcodable.subtype hp; exact
id └─────────────────┘ └┘
src └───────┘└─────────────────┘┴ └─────
typ └───────┘└─────────────────┘┴└┘ └─────
doc └───────┘ ┴ └─────
txt └───────┘ ┴ └─────
par └───────┘ ┴ └─────
pid ┴└─┘ ┴ └
st └───────────────────────────────────────
1040 primrec (@subtype.val α p) :=
id └─────┘ └─────────┘ ┴ ┴
src ─┘└─────┘┴ └─────────┘┴ ┴ └┘
typ ─┘└─────┘┴ └─────────┘┴┴┴┴└┘
doc ─┘└─────┘┴ ┴ ┴ └┘
txt ─┘ ┴ ┴ ┴ └┘
par ─┘ ┴ ┴ ┴ └┘
pid ─┘ ┴ ┴ ┴ ┴┴
st ────────────────────────────┘
1041 begin
st └─────
1042 letI := primcodable.subtype hp,
id └─────────────────┘ └┘
src └──────┘└─────────────────┘┴
typ └──────┘└─────────────────┘┴└┘
doc └──────┘ ┴
txt └──────┘ ┴
par └──────┘ ┴
pid ┴└─┘ ┴
st ───────────────────────────────┘└─
1043 refine (primcodable.prim (subtype p)).of_eq (λ n, _),
id └──────────────┘ └─────┘ ┴
src └─────┘ └──────────────┘┴ └─────┘┴ └───────┘ └────┘
typ └─────┘ └──────────────┘┴ └─────┘┴┴└───────┘ └────┘
doc └─────┘ ┴ ┴ └───────┘ └────┘
txt └─────┘ ┴ ┴ └───────┘ └────┘
par └─────┘ ┴ ┴ └───────┘ └────┘
pid ┴ ┴ ┴ └───────┘ └────┘
st ─────────────────────────────────────────────────────┘└─
1044 rcases decode (subtype p) n with _|⟨a,h⟩; refl
id └────┘ └─────┘ ┴ ┴
src └─────┘└────┘┴ └─────┘┴ └┘ └───────────┘ └───┘
typ └─────┘└────┘┴ └─────┘┴┴└┘┴└───────────┘ └───┘
doc └─────┘ ┴ ┴ └┘ └───────────┘ └───┘
txt └─────┘ ┴ ┴ └┘ └───────────┘ └───┘
par └─────┘ ┴ ┴ └┘ └───────────┘ └───┘
pid ┴ ┴ ┴ └┘ └───────────┘ ┴
st ────────────────────────────────────────────────┘
1045 end
st └─┘
1046
1047 theorem subtype_val_iff {p : β → Prop} [decidable_pred p]
id ┴ └────────────┘ ┴
src └────────────┘
typ ┴ └────────────┘ ┴
1048 {hp : primrec_pred p} {f : α → subtype p} :
id └──────────┘ ┴ ┴ └─────┘ ┴
src └──────────┘ └─────┘
typ └──────────┘ ┴ ┴ └─────┘ ┴
doc └──────────┘
1049 by haveI := primcodable.subtype hp; exact
id └─────────────────┘ └┘
src └───────┘└─────────────────┘┴ └─────
typ └───────┘└─────────────────┘┴└┘ └─────
doc └───────┘ ┴ └─────
txt └───────┘ ┴ └─────
par └───────┘ ┴ └─────
pid ┴└─┘ ┴ └
st └───────────────────────────────────────
1050 primrec (λ a, (f a).1) ↔ primrec f :=
id ┴ └─────┘ ┴
src ─┘ ┴ └──┘ ┴ └───┘┴┴└─────┘┴ ┴
typ ─┘ ┴ └──┘ ┴ └───┘┴┴└─────┘┴┴┴
doc ─┘ ┴ └──┘ ┴ └───┘ ┴└─────┘┴ ┴
txt ─┘ ┴ └──┘ ┴ └───┘ ┴ ┴ ┴
par ─┘ ┴ └──┘ ┴ └───┘ ┴ ┴ ┴
pid ─┘ ┴ └──┘ ┴ └───┘ ┴ ┴ ┴
st ────────────────────────────────────┘
1051 begin
st └─────
1052 letI := primcodable.subtype hp,
id └─────────────────┘ └┘
src └──────┘└─────────────────┘┴
typ └──────┘└─────────────────┘┴└┘
doc └──────┘ ┴
txt └──────┘ ┴
par └──────┘ ┴
pid ┴└─┘ ┴
st ───────────────────────────────┘└─
1053 refine ⟨λ h, _, λ hf, subtype_val.comp hf⟩,
id └──────────────┘
src └─────┘ └─────┘ └───┘└──────────────┘┴ ┴
typ └─────┘ └─────┘ └───┘└──────────────┘┴ ┴
doc └─────┘ └─────┘ └───┘ ┴ ┴
txt └─────┘ └─────┘ └───┘ ┴ ┴
par └─────┘ └─────┘ └───┘ ┴ ┴
pid ┴ └─────┘ └───┘ ┴ ┴
st ───────────────────────────────────────────┘└─
1054 refine nat.primrec.of_eq h (λ n, _),
id └───────────────┘ ┴
src └─────┘└───────────────┘┴ ┴ └────┘
typ └─────┘└───────────────┘┴┴┴ └────┘
doc └─────┘ ┴ ┴ └────┘
txt └─────┘ ┴ ┴ └────┘
par └─────┘ ┴ ┴ └────┘
pid ┴ ┴ ┴ └────┘
st ────────────────────────────────────┘└─
1055 cases decode α n with a, {refl},
id └────┘ ┴ ┴
src └────┘└────┘┴ ┴ └─────┘ └──┘
typ └────┘└────┘┴┴┴┴└─────┘ └──┘
doc └────┘ ┴ ┴ └─────┘ └──┘
txt └────┘ ┴ ┴ └─────┘ └──┘
par └────┘ ┴ ┴ └─────┘ └──┘
pid ┴ ┴ ┴ └─────┘
st ────────────────────────┘└─────┘└┘└
1056 simp, cases f a; refl
id ┴ ┴
src └──┘ └────┘ ┴ └───┘
typ └──┘ └────┘┴┴┴ └───┘
doc └──┘ └────┘ ┴ └───┘
txt └──┘ └────┘ ┴ └───┘
par └──┘ └────┘ ┴ └───┘
pid ┴ ┴ ┴
st ─────┘└────────────────┘
1057 end
st └─┘
1058
1059 theorem fin_val_iff {n} {f : α → fin n} :
id ┴ └─┘ ┴
src └─┘
typ ┴ └─┘ ┴
1060 primrec (λ a, (f a).1) ↔ primrec f :=
id └─────┘ ┴ ┴ ┴ ┴ ┴ └─────┘ ┴
src └─────┘ ┴ ┴ └─────┘
typ └─────┘ ┴ ┴ ┴ ┴ ┴ └─────┘ ┴
doc └─────┘ └─────┘
1061 begin
st └─────
1062 let : primcodable {a//id a<n}, swap,
id └─────────┘ ┴ └┘ ┴┴
src └────┘└─────────┘┴┴└─┘└┘┴ ┴ ┴ └──┘
typ └────┘└─────────┘┴┴└─┘└┘┴ ┴┴┴ └──┘
doc └────┘└─────────┘┴ └─┘ ┴ ┴ └──┘
txt └────┘ ┴ └─┘ ┴ ┴ └──┘
par └────┘ ┴ └─┘ ┴ ┴ └──┘
pid └──┘└┘ ┴ └─┘ ┴ ┴
st ──────────────────────────────┘└────┘└─
1063 exactI (iff.trans (by refl) subtype_val_iff).trans (of_equiv_iff _)
id └───────┘ └─────────────┘ └──────────┘
src └─────┘ └───────┘┴ ┴└──┘└┘└─────────────┘└──────┘ └──────────┘└──┘
typ └─────┘ └───────┘┴ ┴└──┘└┘└─────────────┘└──────┘ └──────────┘└──┘
doc └─────┘ ┴ ┴└──┘└┘ └──────┘ └──┘
txt └─────┘ ┴ ┴└──┘└┘ └──────┘ └──┘
par └─────┘ ┴ ┴└──┘└┘ └──────┘ └──┘
pid ┴ ┴ └─────┘ └──────┘ └─┘┴
st ──────────────────────┘└───┘└────────────────────────────────────────┘
1064 end
st └─┘
1065
1066 theorem fin_val {n} : primrec (@fin.val n) := fin_val_iff.2 primrec.id
id └─────┘ └─────┘ ┴ └─────────┘┴ └────────┘
src └─────┘ └─────┘ └─────────┘┴ └────────┘
typ └─────┘ └─────┘ ┴ └─────────┘┴ └────────┘
doc └─────┘
1067
1068 theorem fin_succ {n} : primrec (@fin.succ n) :=
id └─────┘ └──────┘ ┴
src └─────┘ └──────┘
typ └─────┘ └──────┘ ┴
doc └─────┘
1069 fin_val_iff.1 $ by simp [succ.comp fin_val]
id └─────────┘┴ └───────┘ └─────┘
src └─────────┘┴ └────┘└───────┘┴└─────┘└─
typ └─────────┘┴ └────┘└───────┘┴└─────┘└─
doc └────┘ ┴ └─
txt └────┘ ┴ └─
par └────┘ ┴ └─
pid ┴┴ ┴ ┴└
st └─────────────────────────
1070
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1071 theorem vector_to_list {n} : primrec (@vector.to_list α n) := subtype_val
id └─────┘ └────────────┘ ┴ ┴ └─────────┘
src └─────┘ └────────────┘ └─────────┘
typ └─────┘ └────────────┘ ┴ ┴ └─────────┘
doc └─────┘
1072
1073 theorem vector_to_list_iff {n} {f : α → vector β n} :
id ┴ └────┘ ┴ ┴
src └────┘
typ ┴ └────┘ ┴ ┴
1074 primrec (λ a, (f a).to_list) ↔ primrec f := subtype_val_iff
id └─────┘ ┴ ┴ ┴ └─────┘ ┴ └─────┘ ┴ └─────────────┘
src └─────┘ └─────┘ ┴ └─────┘ └─────────────┘
typ └─────┘ ┴ ┴ ┴ └─────┘ ┴ └─────┘ ┴ └─────────────┘
doc └─────┘ └─────┘
1075
1076 theorem vector_cons {n} : primrec₂ (@vector.cons α n) :=
id └──────┘ └─────────┘ ┴ ┴
src └──────┘ └─────────┘
typ └──────┘ └─────────┘ ┴ ┴
doc └──────┘
1077 vector_to_list_iff.1 $ by simp; exact
id └────────────────┘┴
src └────────────────┘┴ └──┘ └────┘
typ └────────────────┘┴ └──┘ └────┘
doc └──┘ └────┘
txt └──┘ └────┘
par └──┘ └────┘
pid ┴
st └────────────
1078 list_cons.comp fst (vector_to_list_iff.2 snd)
id └────────────┘ └─┘ └────────────────┘ └─┘
src └────────────┘┴└─┘┴ └────────────────┘└─┘└─┘└─
typ └────────────┘┴└─┘┴ └────────────────┘└─┘└─┘└─
doc ┴ ┴ └─┘ └─
txt ┴ ┴ └─┘ └─
par ┴ ┴ └─┘ └─
pid ┴ ┴ └─┘ ┴└
st ──────────────────────────────────────────────
1079
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1080 theorem vector_length {n} : primrec (@vector.length α n) := const _
id └─────┘ └───────────┘ ┴ ┴ └───┘
src └─────┘ └───────────┘ └───┘
typ └─────┘ └───────────┘ ┴ ┴ └───┘
doc └─────┘
1081
1082 theorem vector_head {n} : primrec (@vector.head α n) :=
id └─────┘ └─────────┘ ┴ ┴
src └─────┘ └─────────┘
typ └─────┘ └─────────┘ ┴ ┴
doc └─────┘
1083 option_some_iff.1 $
id └─────────────┘┴
src └─────────────┘┴
typ └─────────────┘┴
1084 (list_head'.comp vector_to_list).of_eq $ λ ⟨a::l, h⟩, rfl
id └────────┘└───┘ └────────────┘ └───┘ ┴ └┘ └─┘
src └────────┘└───┘ └────────────┘ └───┘ └┘ └─┘
typ └────────┘└───┘ └────────────┘ └───┘ ┴ └┘ └─┘
1085
1086 theorem vector_tail {n} : primrec (@vector.tail α n) :=
id └─────┘ └─────────┘ ┴ ┴
src └─────┘ └─────────┘
typ └─────┘ └─────────┘ ┴ ┴
doc └─────┘
1087 vector_to_list_iff.1 $ (list_tail.comp vector_to_list).of_eq $
id └────────────────┘┴ └───────┘└───┘ └────────────┘ └───┘
src └────────────────┘┴ └───────┘└───┘ └────────────┘ └───┘
typ └────────────────┘┴ └───────┘└───┘ └────────────┘ └───┘
1088 λ ⟨l, h⟩, by cases l; refl
id ┴ ┴
src └────┘ └────
typ ┴ └────┘┴ └────
doc └────┘ └────
txt └────┘ └────
par └────┘ └────
pid ┴ └
st └──────────────
1089
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1090 theorem vector_nth {n} : primrec₂ (@vector.nth α n) :=
id └──────┘ └────────┘ ┴ ┴
src └──────┘ └────────┘
typ └──────┘ └────────┘ ┴ ┴
doc └──────┘
1091 option_some_iff.1 $
id └─────────────┘┴
src └─────────────┘┴
typ └─────────────┘┴
1092 (list_nth.comp (vector_to_list.comp fst) (fin_val.comp snd)).of_eq $
id └──────┘└───┘ └────────────┘└───┘ └─┘ └─────┘└───┘ └─┘ └───┘
src └──────┘└───┘ └────────────┘└───┘ └─┘ └─────┘└───┘ └─┘ └───┘
typ └──────┘└───┘ └────────────┘└───┘ └─┘ └─────┘└───┘ └─┘ └───┘
1093 λ a, by simp [vector.nth_eq_nth_le]; rw [← list.nth_le_nth]
id ┴ └──────────────────┘ └─────────────┘
src └────┘└──────────────────┘┴ └────┘└─────────────┘└─
typ ┴ └────┘└──────────────────┘┴ └────┘└─────────────┘└─
doc └────┘ ┴ └────┘ └─
txt └────┘ ┴ └────┘ └─
par └────┘ ┴ └────┘ └─
pid ┴┴ ┴ └──┘ ┴└
st └────────────────────────────────┘└───────────────┘┴└
1094
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1095 theorem list_of_fn : ∀ {n} {f : fin n → α → σ},
id ┴┴ └─┘ ┴ ┴ ┴ ┴
src └─┘
typ ┴┴ └─┘ ┴ ┴ ┴ ┴
1096 (∀ i, primrec (f i)) → primrec (λ a, list.of_fn (λ i, f i a))
id ┴ └─────┘ ┴ ┴ └─────┘ ┴ └────────┘ ┴ ┴ ┴ ┴
src └─────┘ └─────┘ └────────┘
typ ┴ └─────┘ ┴ ┴ └─────┘ ┴ └────────┘ ┴ ┴ ┴ ┴
doc └─────┘ └─────┘
1097 | 0 f hf := const []
id └───┘ └┘
src └───┘ └┘
typ └───┘ └┘
1098 | (n+1) f hf := by simp [list.of_fn_succ]; exact
id ┴ └─────────────┘
src ┴ └────┘└─────────────┘┴ └─────
typ ┴ └────┘└─────────────┘┴ └─────
doc └────┘ ┴ └─────
txt └────┘ ┴ └─────
par └────┘ ┴ └─────
pid ┴┴ ┴ └
st └──────────────────────────────
1099 list_cons.comp (hf 0) (list_of_fn (λ i, hf i.succ))
id └────────────┘ └────────┘ └┘ └───┘
src ─┘└────────────┘┴ └──┘ ┴ └──┘ ┴ └───┘└──
typ ─┘└────────────┘┴ └──┘ └────────┘┴ └──┘└┘┴ └───┘└──
doc ─┘ ┴ └──┘ ┴ └──┘ ┴ └──
txt ─┘ ┴ └──┘ ┴ └──┘ ┴ └──
par ─┘ ┴ └──┘ ┴ └──┘ ┴ └──
pid ─┘ ┴ └──┘ ┴ └──┘ ┴ └┘└
st ──────────────────────────────────────────────────────
1100
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1101 theorem vector_of_fn {n} {f : fin n → α → σ}
id └─┘ ┴ ┴ ┴
src └─┘
typ └─┘ ┴ ┴ ┴
1102 (hf : ∀ i, primrec (f i)) : primrec (λ a, vector.of_fn (λ i, f i a)) :=
id ┴ └─────┘ ┴ ┴ └─────┘ ┴ └──────────┘ ┴ ┴ ┴ ┴
src └─────┘ └─────┘ └──────────┘
typ ┴ └─────┘ ┴ ┴ └─────┘ ┴ └──────────┘ ┴ ┴ ┴ ┴
doc └─────┘ └─────┘
1103 vector_to_list_iff.1 $ by simp [list_of_fn hf]
id └────────────────┘┴ └────────┘ └┘
src └────────────────┘┴ └────┘└────────┘┴ └─
typ └────────────────┘┴ └────┘└────────┘┴└┘└─
doc └────┘ ┴ └─
txt └────┘ ┴ └─
par └────┘ ┴ └─
pid ┴┴ ┴ ┴└
st └─────────────────────
1104
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1105 theorem vector_nth' {n} : primrec (@vector.nth α n) := of_equiv_symm
id └─────┘ └────────┘ ┴ ┴ └───────────┘
src └─────┘ └────────┘ └───────────┘
typ └─────┘ └────────┘ ┴ ┴ └───────────┘
doc └─────┘
1106
1107 theorem vector_of_fn' {n} : primrec (@vector.of_fn α n) := of_equiv
id └─────┘ └──────────┘ ┴ ┴ └──────┘
src └─────┘ └──────────┘ └──────┘
typ └─────┘ └──────────┘ ┴ ┴ └──────┘
doc └─────┘
1108
1109 theorem fin_app {n} : primrec₂ (@id (fin n → σ)) :=
id └──────┘ └┘ └─┘ ┴ ┴
src └──────┘ └┘ └─┘
typ └──────┘ └┘ └─┘ ┴ ┴
doc └──────┘
1110 (vector_nth.comp (vector_of_fn'.comp fst) snd).of_eq $
id └────────┘└───┘ └───────────┘└───┘ └─┘ └─┘ └───┘
src └────────┘└───┘ └───────────┘└───┘ └─┘ └─┘ └───┘
typ └────────┘└───┘ └───────────┘└───┘ └─┘ └─┘ └───┘
1111 λ ⟨v, i⟩, by simp
id ┴
src └────
typ ┴ └────
doc └────
txt └────
par └────
pid └
st └─────
1112
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1113 theorem fin_curry₁ {n} {f : fin n → α → σ} : primrec₂ f ↔ ∀ i, primrec (f i) :=
id └─┘ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ └─────┘ ┴ ┴
src └─┘ └──────┘ ┴ └─────┘
typ └─┘ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ └─────┘ ┴ ┴
doc └──────┘ └─────┘
1114 ⟨λ h i, h.comp (const i) primrec.id,
id ┴ ┴ ┴└───┘ └───┘ ┴ └────────┘
src └───┘ └───┘ └────────┘
typ ┴ ┴ ┴└───┘ └───┘ ┴ └────────┘
1115 λ h, (vector_nth.comp ((vector_of_fn h).comp snd) fst).of_eq $ λ a, by simp⟩
id ┴ └────────┘└───┘ └──────────┘ ┴ └──┘ └─┘ └─┘ └───┘ ┴
src └────────┘└───┘ └──────────┘ └──┘ └─┘ └─┘ └───┘ └──┘
typ ┴ └────────┘└───┘ └──────────┘ ┴ └──┘ └─┘ └─┘ └───┘ ┴ └──┘
doc └──┘
txt └──┘
par └──┘
st └───┘
1116
1117 theorem fin_curry {n} {f : α → fin n → σ} : primrec f ↔ primrec₂ f :=
id ┴ └─┘ ┴ ┴ └─────┘ ┴ ┴ └──────┘ ┴
src └─┘ └─────┘ ┴ └──────┘
typ ┴ └─┘ ┴ ┴ └─────┘ ┴ ┴ └──────┘ ┴
doc └─────┘ └──────┘
1118 ⟨λ h, fin_app.comp (h.comp fst) snd,
id ┴ └─────┘└───┘ ┴└───┘ └─┘ └─┘
src └─────┘└───┘ └───┘ └─┘ └─┘
typ ┴ └─────┘└───┘ ┴└───┘ └─┘ └─┘
1119 λ h, (vector_nth'.comp (vector_of_fn (λ i,
id ┴ └─────────┘└───┘ └──────────┘ ┴
src └─────────┘└───┘ └──────────┘
typ ┴ └─────────┘└───┘ └──────────┘ ┴
1120 show primrec (λ a, f a i), from
id └─────┘ ┴ ┴ ┴ ┴
src └─────┘
typ └─────┘ ┴ ┴ ┴ ┴
doc └─────┘
1121 h.comp primrec.id (const i)))).of_eq $
id ┴└───┘ └────────┘ └───┘ ┴ └───┘
src └───┘ └────────┘ └───┘ └───┘
typ ┴└───┘ └────────┘ └───┘ ┴ └───┘
1122 λ a, by funext i; simp⟩
id ┴
src └──────┘ └──┘
typ ┴ └──────┘ └──┘
doc └──────┘ └──┘
txt └──────┘ └──┘
par └──────┘ └──┘
pid └┘
st └─────────────┘
1123
1124 end primrec
1125
1126 namespace nat
1127 open vector
1128
1129 /-- An alternative inductive definition of `primrec` which
1130 does not use the pairing function on ℕ, and so has to
1131 work with n-ary functions on ℕ instead of unary functions.
1132 We prove that this is equivalent to the regular notion
1133 in `to_prim` and `of_prim`. -/
1134 inductive primrec' : ∀ {n}, (vector ℕ n → ℕ) → Prop
id ┴ └────┘ ┴ ┴ ┴ ┴
src └────┘ ┴ ┴
typ ┴ └────┘ ┴ ┴ ┴ ┴
1135 | zero : @primrec' 0 (λ _, 0)
id ┴
typ ┴
1136 | succ : @primrec' 1 (λ v, succ v.head)
id ┴ └──┘ ┴└───┘
src └──┘ └───┘
typ ┴ └──┘ ┴└───┘
1137 | nth {n} (i : fin n) : primrec' (λ v, v.nth i)
id ┴ └─┘ ┴ ┴ ┴└──┘ ┴
src └─┘ └──┘
typ ┴ └─┘ ┴ ┴ ┴└──┘ ┴
1138 | comp {m n f} (g : fin n → vector ℕ m → ℕ) :
id ┴ ┴ ┴ └─┘ ┴ ┴ └────┘ ┴ ┴ ┴
src └─┘ └────┘ ┴ ┴
typ ┴ ┴ ┴ └─┘ ┴ ┴ └────┘ ┴ ┴ ┴
1139 primrec' f → (∀ i, primrec' (g i)) →
id └──────┘ ┴ ┴ ┴ ┴
typ └──────┘ ┴ ┴ ┴ ┴
1140 primrec' (λ a, f (of_fn (λ i, g i a)))
id ┴ ┴ └───┘ ┴ ┴ ┴ ┴
src └───┘
typ ┴ ┴ └───┘ ┴ ┴ ┴ ┴
1141 | prec {n f g} : @primrec' n f → @primrec' (n+2) g →
id ┴ ┴ ┴ └──────┘ ┴ ┴ └──────┘ ┴┴ ┴
src ┴
typ ┴ ┴ ┴ └──────┘ ┴ ┴ └──────┘ ┴┴ ┴
1142 primrec' (λ v : vector ℕ (n+1),
id └────┘ ┴ ┴┴
src └────┘ ┴ ┴
typ └────┘ ┴ ┴┴
1143 v.head.elim (f v.tail) (λ y IH, g (y :: IH :: v.tail)))
id ┴└───┘└───┘ ┴ ┴└───┘ ┴ └┘ ┴ ┴ └┘ └┘ └┘ ┴└───┘
src └───┘└───┘ └───┘ └┘ └┘ └───┘
typ ┴└───┘└───┘ ┴ ┴└───┘ ┴ └┘ ┴ ┴ └┘ └┘ └┘ ┴└───┘
1144
1145 end nat
1146
1147 namespace nat.primrec'
1148 open vector primrec nat (primrec') nat.primrec'
1149 hide ite
1150
1151 theorem to_prim {n f} (pf : @primrec' n f) : primrec f :=
id └──────┘ ┴ ┴ └─────┘ ┴
src └──────┘ └─────┘
typ └──────┘ ┴ ┴ └─────┘ ┴
doc └──────┘ └─────┘
1152 begin
st └─────
1153 induction pf,
id └┘
src └────────┘
typ └────────┘└┘
doc └────────┘
txt └────────┘
par └────────┘
pid ┴
st ─────────────┘└─
1154 case nat.primrec'.zero { exact const 0 },
id └───┘
src └───────────────────────┘└────┘└───┘└─┘┴
typ └───────────────────────┘└────┘└───┘└─┘┴
doc └───────────────────────┘└────┘ └─┘┴
txt └───────────────────────┘└────┘ └─┘┴
par └───────────────────────┘└────┘ └─┘┴
pid └────────────────┘┴└──────┘ └──┘
st ─────────────────────────┘└─────────────┘└┘└
1155 case nat.primrec'.succ { exact primrec.succ.comp vector_head },
id └───────────────┘ └─────────┘
src └───────────────────────┘└────┘└───────────────┘┴└─────────┘┴┴
typ └───────────────────────┘└────┘└───────────────┘┴└─────────┘┴┴
doc └───────────────────────┘└────┘ ┴ ┴┴
txt └───────────────────────┘└────┘ ┴ ┴┴
par └───────────────────────┘└────┘ ┴ ┴┴
pid └────────────────┘┴└──────┘ ┴ └┘
st ─────────────────────────┘└───────────────────────────────────┘└┘└
1156 case nat.primrec'.nth : n i {
src └─────────────────────────────
typ └─────────────────────────────
doc └─────────────────────────────
txt └─────────────────────────────
par └─────────────────────────────
pid └───────────────┘└────┘└──
st ──────────────────────────────┘└
1157 exact vector_nth.comp primrec.id (const i) },
id └─────────────┘ └────────┘ └───┘ ┴
src ───┘└────┘└─────────────┘┴└────────┘┴ └───┘┴ └┘┴
typ ───┘└────┘└─────────────┘┴└────────┘┴ └───┘┴┴└┘┴
doc ───┘└────┘ ┴ ┴ ┴ └┘┴
txt ───┘└────┘ ┴ ┴ ┴ └┘┴
par ───┘└────┘ ┴ ┴ ┴ └┘┴
pid ─────────┘ ┴ ┴ ┴ └─┘
st ──────────────────────────────────────────────┘└┘└
1158 case nat.primrec'.comp : m n f g _ _ hf hg {
src └────────────────────────────────────────────
typ └────────────────────────────────────────────
doc └────────────────────────────────────────────
txt └────────────────────────────────────────────
par └────────────────────────────────────────────
pid └────────────────┘└──────────────────┘└──
st ─────────────────────────────────────────────┘└
1159 exact hf.comp (vector_of_fn (λ i, hg i)) },
id └─────┘ └──────────┘ └┘
src ───┘└────┘└─────┘┴ └──────────┘┴ └──┘ ┴ └─┘┴
typ ───┘└────┘└─────┘┴ └──────────┘┴ └──┘└┘┴ └─┘┴
doc ───┘└────┘ ┴ ┴ └──┘ ┴ └─┘┴
txt ───┘└────┘ ┴ ┴ └──┘ ┴ └─┘┴
par ───┘└────┘ ┴ ┴ └──┘ ┴ └─┘┴
pid ─────────┘ ┴ ┴ └──┘ ┴ └──┘
st ────────────────────────────────────────────┘└┘└
1160 case nat.primrec'.prec : n f g _ _ hf hg {
src └──────────────────────────────────────────
typ └──────────────────────────────────────────
doc └──────────────────────────────────────────
txt └──────────────────────────────────────────
par └──────────────────────────────────────────
pid └────────────────┘└────────────────┘└──
st ───────────────────────────────────────────┘└
1161 exact nat_elim' vector_head (hf.comp vector_tail) (hg.comp $
id └───────┘ └─────────┘ └─────┘ └─────┘
src ───┘└────┘└───────┘┴└─────────┘┴ └─────┘┴ └┘ └─────┘┴ └
typ ───┘└────┘└───────┘┴└─────────┘┴ └─────┘┴ └┘ └─────┘┴ └
doc ───┘└────┘ ┴ ┴ ┴ └┘ ┴ └
txt ───┘└────┘ ┴ ┴ ┴ └┘ ┴ └
par ───┘└────┘ ┴ ┴ ┴ └┘ ┴ └
pid ─────────┘ ┴ ┴ ┴ └┘ ┴ └
st ─────────────────────────────────────────────────────────────────
1162 vector_cons.comp (fst.comp snd) $
id └──────┘
src ─────┘ ┴ └──────┘┴ └┘ └
typ ─────┘ ┴ └──────┘┴ └┘ └
doc ─────┘ ┴ ┴ └┘ └
txt ─────┘ ┴ ┴ └┘ └
par ─────┘ ┴ ┴ └┘ └
pid ─────┘ ┴ ┴ └┘ └
st ────────────────────────────────────────
1163 vector_cons.comp (snd.comp snd) $
id └──────────────┘ └──────┘ └─┘
src ─────┘└──────────────┘┴ └──────┘┴└─┘└┘ └
typ ─────┘└──────────────┘┴ └──────┘┴└─┘└┘ └
doc ─────┘ ┴ ┴ └┘ └
txt ─────┘ ┴ ┴ └┘ └
par ─────┘ ┴ ┴ └┘ └
pid ─────┘ ┴ ┴ └┘ └
st ────────────────────────────────────────
1164 (@vector_tail _ _ (n+1)).comp fst).to₂ },
id └─────────┘ ┴┴ └─┘
src ─────┘ └─────────┘└───┘ ┴└───────┘└─┘└────┘┴
typ ─────┘ └─────────┘└───┘ ┴┴└───────┘└─┘└────┘┴
doc ─────┘ └───┘ └───────┘ └────┘┴
txt ─────┘ └───┘ └───────┘ └────┘┴
par ─────┘ └───┘ └───────┘ └────┘┴
pid ─────┘ └───┘ └───────┘ └─────┘
st ────────────────────────────────────────────┘└──
1165 end
st ──┘
1166
1167 theorem of_eq {n} {f g : vector ℕ n → ℕ}
id └────┘ ┴ ┴ ┴
src └────┘ ┴ ┴
typ └────┘ ┴ ┴ ┴
1168 (hf : primrec' f) (H : ∀ i, f i = g i) : primrec' g :=
id └──────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──────┘ ┴
src └──────┘ ┴ └──────┘
typ └──────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──────┘ ┴
doc └──────┘ └──────┘
1169 (funext H : f = g) ▸ hf
id └────┘ ┴ ┴ ┴ ┴ ┴ └┘
src └────┘ ┴ ┴
typ └────┘ ┴ ┴ ┴ ┴ ┴ └┘
1170
1171 theorem const {n} : ∀ m, @primrec' n (λ v, m)
id ┴ └──────┘ ┴ ┴ ┴
src └──────┘
typ ┴ └──────┘ ┴ ┴ ┴
doc └──────┘
1172 | 0 := zero.comp fin.elim0 (λ i, i.elim0)
id └──┘└───┘ └───────┘ ┴ ┴└────┘
src └───────┘ └───────┘ └────┘
typ └──┘└───┘ └───────┘ ┴ ┴└────┘
1173 | (m+1) := succ.comp _ (λ i, const m)
id ┴┴ └──┘└───┘ ┴ └───┘
src ┴ └───────┘
typ ┴┴ └──┘└───┘ ┴ └───┘
1174
1175 theorem head {n : ℕ} : @primrec' n.succ head :=
id ┴ └──────┘ ┴└───┘ └──┘
src ┴ └──────┘ └───┘ └──┘
typ ┴ └──────┘ ┴└───┘ └──┘
doc └──────┘
1176 (nth 0).of_eq $ λ v, by simp [nth_zero]
id └─┘ └───┘ ┴ └──────┘
src └─┘ └───┘ └────┘└──────┘└─
typ └─┘ └───┘ ┴ └────┘└──────┘└─
doc └────┘ └─
txt └────┘ └─
par └────┘ └─
pid ┴┴ ┴└
st └────────────────
1177
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1178 theorem tail {n f} (hf : @primrec' n f) : @primrec' n.succ (λ v, f v.tail) :=
id └──────┘ ┴ ┴ └──────┘ ┴└───┘ ┴ ┴ ┴└───┘
src └──────┘ └──────┘ └───┘ └───┘
typ └──────┘ ┴ ┴ └──────┘ ┴└───┘ ┴ ┴ ┴└───┘
doc └──────┘ └──────┘
1179 (hf.comp _ (λ i, @nth _ i.succ)).of_eq $
id └┘└───┘ ┴ └─┘ ┴└───┘ └───┘
src └───┘ └─┘ └───┘ └───┘
typ └┘└───┘ ┴ └─┘ ┴└───┘ └───┘
1180 λ v, by rw [← of_fn_nth v.tail]; congr; funext i; simp
id ┴ └───────┘ └────┘
src └────┘└───────┘┴└────┘┴ └───┘ └──────┘ └────
typ ┴ └────┘└───────┘┴└────┘┴ └───┘ └──────┘ └────
doc └────┘ ┴ ┴ └──────┘ └────
txt └────┘ ┴ ┴ └───┘ └──────┘ └────
par └────┘ ┴ ┴ └───┘ └──────┘ └────
pid └──┘ ┴ ┴ └┘ └
st └─────────────────────┘┴└───────────────────────
1181
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1182 def vec {n m} (f : vector ℕ n → vector ℕ m) :=
id └────┘ ┴ ┴ └────┘ ┴ ┴
src └────┘ ┴ └────┘ ┴
typ └────┘ ┴ ┴ └────┘ ┴ ┴
1183 ∀ i, primrec' (λ v, (f v).nth i)
id ┴ └──────┘ ┴ ┴ ┴ └─┘ ┴
src └──────┘ └─┘
typ ┴ └──────┘ ┴ ┴ ┴ └─┘ ┴
doc └──────┘
1184
1185 protected theorem nil {n} : @vec n 0 (λ _, nil) := λ i, i.elim0
id └─┘ ┴ ┴ └─┘ ┴ ┴└────┘
src └─┘ └─┘ └────┘
typ └─┘ ┴ ┴ └─┘ ┴ ┴└────┘
1186
1187 protected theorem cons {n m f g}
1188 (hf : @primrec' n f) (hg : @vec n m g) :
id └──────┘ ┴ ┴ └─┘ ┴ ┴ ┴
src └──────┘ └─┘
typ └──────┘ ┴ ┴ └─┘ ┴ ┴ ┴
doc └──────┘
1189 vec (λ v, f v :: g v) :=
id └─┘ ┴ ┴ ┴ └┘ ┴ ┴
src └─┘ └┘
typ └─┘ ┴ ┴ ┴ └┘ ┴ ┴
1190 λ i, fin.cases (by simp *) (λ i, by simp [hg i]) i
id ┴ └───────┘ ┴ └┘ ┴ ┴
src └───────┘ └────┘ └────┘ ┴ ┴
typ ┴ └───────┘ └────┘ ┴ └────┘└┘┴┴┴ ┴
doc └────┘ └────┘ ┴ ┴
txt └────┘ └────┘ ┴ ┴
par └────┘ └────┘ ┴ ┴
pid ┴┴ ┴┴ ┴ ┴
st └─────┘ └──────────┘
1191
1192 theorem idv {n} : @vec n n id := nth
id └─┘ ┴ ┴ └┘ └─┘
src └─┘ └┘ └─┘
typ └─┘ ┴ ┴ └┘ └─┘
1193
1194 theorem comp' {n m f g}
1195 (hf : @primrec' m f) (hg : @vec n m g) :
id └──────┘ ┴ ┴ └─┘ ┴ ┴ ┴
src └──────┘ └─┘
typ └──────┘ ┴ ┴ └─┘ ┴ ┴ ┴
doc └──────┘
1196 primrec' (λ v, f (g v)) :=
id └──────┘ ┴ ┴ ┴ ┴
src └──────┘
typ └──────┘ ┴ ┴ ┴ ┴
doc └──────┘
1197 (hf.comp _ hg).of_eq $ λ v, by simp
id └┘└───┘ └┘ └───┘ ┴
src └───┘ └───┘ └────
typ └┘└───┘ └┘ └───┘ ┴ └────
doc └────
txt └────
par └────
pid └
st └─────
1198
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1199 theorem comp₁ (f : ℕ → ℕ) (hf : @primrec' 1 (λ v, f v.head))
id ┴ ┴ └──────┘ ┴ ┴ ┴└───┘
src ┴ ┴ └──────┘ └───┘
typ ┴ ┴ └──────┘ ┴ ┴ ┴└───┘
doc └──────┘
1200 {n g} (hg : @primrec' n g) : primrec' (λ v, f (g v)) :=
id └──────┘ ┴ ┴ └──────┘ ┴ ┴ ┴ ┴
src └──────┘ └──────┘
typ └──────┘ ┴ ┴ └──────┘ ┴ ┴ ┴ ┴
doc └──────┘ └──────┘
1201 hf.comp _ (λ i, hg)
id └┘└───┘ ┴ └┘
src └───┘
typ └┘└───┘ ┴ └┘
1202
1203 theorem comp₂ (f : ℕ → ℕ → ℕ)
id ┴ ┴ ┴
src ┴ ┴ ┴
typ ┴ ┴ ┴
1204 (hf : @primrec' 2 (λ v, f v.head v.tail.head))
id └──────┘ ┴ ┴ ┴└───┘ ┴└───┘└───┘
src └──────┘ └───┘ └───┘└───┘
typ └──────┘ ┴ ┴ ┴└───┘ ┴└───┘└───┘
doc └──────┘
1205 {n g h} (hg : @primrec' n g) (hh : @primrec' n h) :
id └──────┘ ┴ ┴ └──────┘ ┴ ┴
src └──────┘ └──────┘
typ └──────┘ ┴ ┴ └──────┘ ┴ ┴
doc └──────┘ └──────┘
1206 primrec' (λ v, f (g v) (h v)) :=
id └──────┘ ┴ ┴ ┴ ┴ ┴ ┴
src └──────┘
typ └──────┘ ┴ ┴ ┴ ┴ ┴ ┴
doc └──────┘
1207 by simpa using hf.comp' (hg.cons $ hh.cons primrec'.nil)
id └──────┘ └─────┘ └─────┘ └──────────┘
src └──────────┘└──────┘┴ └─────┘┴ ┴└─────┘┴└──────────┘└─
typ └──────────┘└──────┘┴ └─────┘┴ ┴└─────┘┴└──────────┘└─
doc └──────────┘ ┴ ┴ ┴ ┴ └─
txt └──────────┘ ┴ ┴ ┴ ┴ └─
par └──────────┘ ┴ ┴ ┴ ┴ └─
pid ┴└────┘ ┴ ┴ ┴ ┴ ┴└
st └──────────────────────────────────────────────────────
1208
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1209 theorem prec' {n f g h}
1210 (hf : @primrec' n f) (hg : @primrec' n g) (hh : @primrec' (n+2) h) :
id └──────┘ ┴ ┴ └──────┘ ┴ ┴ └──────┘ ┴┴ ┴
src └──────┘ └──────┘ └──────┘ ┴
typ └──────┘ ┴ ┴ └──────┘ ┴ ┴ └──────┘ ┴┴ ┴
doc └──────┘ └──────┘ └──────┘
1211 @primrec' n (λ v, (f v).elim (g v)
id └──────┘ ┴ ┴ ┴ ┴ └──┘ ┴ ┴
src └──────┘ └──┘
typ └──────┘ ┴ ┴ ┴ ┴ └──┘ ┴ ┴
doc └──────┘
1212 (λ (y IH : ℕ), h (y :: IH :: v))) :=
id ┴ ┴ ┴ └┘ └┘ └┘ ┴
src ┴ └┘ └┘
typ ┴ ┴ ┴ └┘ └┘ └┘ ┴
1213 by simpa using comp' (prec hg hh) (hf.cons idv)
id └───┘ └──┘ └┘ └┘ └─────┘ └─┘
src └──────────┘└───┘┴ └──┘┴ ┴ └┘ └─────┘┴└─┘└─
typ └──────────┘└───┘┴ └──┘┴└┘┴└┘└┘ └─────┘┴└─┘└─
doc └──────────┘ ┴ ┴ ┴ └┘ ┴ └─
txt └──────────┘ ┴ ┴ ┴ └┘ ┴ └─
par └──────────┘ ┴ ┴ ┴ └┘ ┴ └─
pid ┴└────┘ ┴ ┴ ┴ └┘ ┴ ┴└
st └─────────────────────────────────────────────
1214
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1215 theorem pred : @primrec' 1 (λ v, v.head.pred) :=
id └──────┘ ┴ ┴└───┘└───┘
src └──────┘ └───┘└───┘
typ └──────┘ ┴ ┴└───┘└───┘
doc └──────┘
1216 (prec' head (const 0) head).of_eq $
id └───┘ └──┘ └───┘ └──┘ └───┘
src └───┘ └──┘ └───┘ └──┘ └───┘
typ └───┘ └──┘ └───┘ └──┘ └───┘
1217 λ v, by simp; cases v.head; refl
id ┴ └────┘
src └──┘ └────┘└────┘ └────
typ ┴ └──┘ └────┘└────┘ └────
doc └──┘ └────┘ └────
txt └──┘ └────┘ └────
par └──┘ └────┘ └────
pid ┴ └
st └─────────────────────────
1218
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1219 theorem add : @primrec' 2 (λ v, v.head + v.tail.head) :=
id └──────┘ ┴ ┴└───┘ ┴ ┴└───┘└───┘
src └──────┘ └───┘ ┴ └───┘└───┘
typ └──────┘ ┴ ┴└───┘ ┴ ┴└───┘└───┘
doc └──────┘
1220 (prec head (succ.comp₁ _ (tail head))).of_eq $
id └──┘ └──┘ └──┘└────┘ └──┘ └──┘ └───┘
src └──┘ └──┘ └──┘└────┘ └──┘ └──┘ └───┘
typ └──┘ └──┘ └──┘└────┘ └──┘ └──┘ └───┘
1221 λ v, by simp; induction v.head; simp [*, nat.succ_add]
id ┴ └────┘ └──────────┘
src └──┘ └────────┘└────┘ └───────┘└──────────┘└─
typ ┴ └──┘ └────────┘└────┘ └───────┘└──────────┘└─
doc └──┘ └────────┘ └───────┘ └─
txt └──┘ └────────┘ └───────┘ └─
par └──┘ └────────┘ └───────┘ └─
pid ┴ ┴└──┘ ┴└
st └───────────────────────────────────────────────
1222
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1223 theorem sub : @primrec' 2 (λ v, v.head - v.tail.head) :=
id └──────┘ ┴ ┴└───┘ ┴ ┴└───┘└───┘
src └──────┘ └───┘ ┴ └───┘└───┘
typ └──────┘ ┴ ┴└───┘ ┴ ┴└───┘└───┘
doc └──────┘
1224 begin
st └─────
1225 suffices, simpa using comp₂ (λ a b, b - a) this (tail head) head,
id └───┘ ┴ └──┘ └──┘ └──┘
src └──────┘ └──────────┘└───┘┴ └────┘ ┴┴┴ └┘ ┴ └──┘┴ └┘└──┘
typ └──────┘ └──────────┘└───┘┴ └────┘ ┴┴┴ └┘└──┘┴ └──┘┴ └┘└──┘
doc └──────┘ └──────────┘ ┴ └────┘ ┴ ┴ └┘ ┴ ┴ └┘
txt └──────┘ └──────────┘ ┴ └────┘ ┴ ┴ └┘ ┴ ┴ └┘
par └──────┘ └──────────┘ ┴ └────┘ ┴ ┴ └┘ ┴ ┴ └┘
pid └──────┘ ┴└────┘ ┴ └────┘ ┴ ┴ └┘ ┴ ┴ └┘
st ─────────┘└──────────────────────────────────────────────────────┘└─
1226 refine (prec head (pred.comp₁ _ (tail head))).of_eq (λ v, _),
id └──┘ └────────┘ └──┘ └──┘
src └─────┘ └──┘┴ ┴ └────────┘└─┘ └──┘┴└──┘└────────┘ └────┘
typ └─────┘ └──┘┴ ┴ └────────┘└─┘ └──┘┴└──┘└────────┘ └────┘
doc └─────┘ ┴ ┴ └─┘ ┴ └────────┘ └────┘
txt └─────┘ ┴ ┴ └─┘ ┴ └────────┘ └────┘
par └─────┘ ┴ ┴ └─┘ ┴ └────────┘ └────┘
pid ┴ ┴ ┴ └─┘ ┴ └────────┘ └────┘
st ─────────────────────────────────────────────────────────────┘└─
1227 simp, induction v.head; simp [*, nat.sub_succ]
id └────┘ └──────────┘
src └──┘ └────────┘└────┘ └───────┘└──────────┘└┘
typ └──┘ └────────┘└────┘ └───────┘└──────────┘└┘
doc └──┘ └────────┘ └───────┘ └┘
txt └──┘ └────────┘ └───────┘ └┘
par └──┘ └────────┘ └───────┘ └┘
pid ┴ ┴└──┘ ┴┴
st ─────┘└─────────────────────────────────────────┘
1228 end
st └─┘
1229
1230 theorem mul : @primrec' 2 (λ v, v.head * v.tail.head) :=
id └──────┘ ┴ ┴└───┘ ┴ ┴└───┘└───┘
src └──────┘ └───┘ ┴ └───┘└───┘
typ └──────┘ ┴ ┴└───┘ ┴ ┴└───┘└───┘
doc └──────┘
1231 (prec (const 0) (tail (add.comp₂ _ (tail head) (head)))).of_eq $
id └──┘ └───┘ └──┘ └─┘└────┘ └──┘ └──┘ └──┘ └───┘
src └──┘ └───┘ └──┘ └─┘└────┘ └──┘ └──┘ └──┘ └───┘
typ └──┘ └───┘ └──┘ └─┘└────┘ └──┘ └──┘ └──┘ └───┘
1232 λ v, by simp; induction v.head; simp [*, nat.succ_mul]; rw add_comm
id ┴ └────┘ └──────────┘ └──────┘
src └──┘ └────────┘└────┘ └───────┘└──────────┘┴ └─┘└──────┘└
typ ┴ └──┘ └────────┘└────┘ └───────┘└──────────┘┴ └─┘└──────┘└
doc └──┘ └────────┘ └───────┘ ┴ └─┘ └
txt └──┘ └────────┘ └───────┘ ┴ └─┘ └
par └──┘ └────────┘ └───────┘ ┴ └─┘ └
pid ┴ ┴└──┘ ┴ ┴ └
st └──────────────────────────────────────────────────┘└──────┘└
1233
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1234 theorem if_lt {n a b f g}
1235 (ha : @primrec' n a) (hb : @primrec' n b)
id └──────┘ ┴ ┴ └──────┘ ┴ ┴
src └──────┘ └──────┘
typ └──────┘ ┴ ┴ └──────┘ ┴ ┴
doc └──────┘ └──────┘
1236 (hf : @primrec' n f) (hg : @primrec' n g) :
id └──────┘ ┴ ┴ └──────┘ ┴ ┴
src └──────┘ └──────┘
typ └──────┘ ┴ ┴ └──────┘ ┴ ┴
doc └──────┘ └──────┘
1237 @primrec' n (λ v, if a v < b v then f v else g v) :=
id └──────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──────┘ ┴
typ └──────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └──────┘
1238 (prec' (sub.comp₂ _ hb ha) hg (tail $ tail hf)).of_eq $
id └───┘ └─┘└────┘ └┘ └┘ └┘ └──┘ └──┘ └┘ └───┘
src └───┘ └─┘└────┘ └──┘ └──┘ └───┘
typ └───┘ └─┘└────┘ └┘ └┘ └┘ └──┘ └──┘ └┘ └───┘
1239 λ v, begin
id ┴
typ ┴
st └─────
1240 cases e : b v - a v,
id ┴ ┴ ┴ ┴
src └────┘ └─┘ ┴ ┴┴┴ ┴
typ └────┘ └─┘┴┴ ┴┴┴┴┴┴
doc └────┘ └─┘ ┴ ┴ ┴ ┴
txt └────┘ └─┘ ┴ ┴ ┴ ┴
par └────┘ └─┘ ┴ ┴ ┴ ┴
pid ┴ └─┘ ┴ ┴ ┴ ┴
st ────────────────────┘└─
1241 { simp [not_lt.2 (nat.le_of_sub_eq_zero e)] },
id └────┘ └───────────────────┘ ┴
src └────┘└────┘└─┘ └───────────────────┘┴ └─┘
typ └────┘└────┘└─┘ └───────────────────┘┴┴└─┘
doc └────┘ └─┘ ┴ └─┘
txt └────┘ └─┘ ┴ └─┘
par └────┘ └─┘ ┴ └─┘
pid ┴┴ └─┘ ┴ └┘┴
st ───┘└────────────────────────────────────────┘└┘└
1242 { simp [nat.lt_of_sub_eq_succ e] }
id └───────────────────┘ ┴
src └────┘└───────────────────┘┴ └┘
typ └────┘└───────────────────┘┴┴└┘
doc └────┘ ┴ └┘
txt └────┘ ┴ └┘
par └────┘ ┴ └┘
pid ┴┴ ┴ ┴┴
st ──────────────────────────────────┘└─
1243 end
st ──┘
1244
1245 theorem mkpair : @primrec' 2 (λ v, v.head.mkpair v.tail.head) :=
id └──────┘ ┴ ┴└───┘└─────┘ ┴└───┘└───┘
src └──────┘ └───┘└─────┘ └───┘└───┘
typ └──────┘ ┴ ┴└───┘└─────┘ ┴└───┘└───┘
doc └──────┘ └─────┘
1246 if_lt head (tail head)
id └───┘ └──┘ └──┘ └──┘
src └───┘ └──┘ └──┘ └──┘
typ └───┘ └──┘ └──┘ └──┘
1247 (add.comp₂ _ (tail $ mul.comp₂ _ head head) head)
id └─┘└────┘ └──┘ └─┘└────┘ └──┘ └──┘ └──┘
src └─┘└────┘ └──┘ └─┘└────┘ └──┘ └──┘ └──┘
typ └─┘└────┘ └──┘ └─┘└────┘ └──┘ └──┘ └──┘
1248 (add.comp₂ _ (add.comp₂ _
id └─┘└────┘ └─┘└────┘
src └─┘└────┘ └─┘└────┘
typ └─┘└────┘ └─┘└────┘
1249 (mul.comp₂ _ head head) head) (tail head))
id └─┘└────┘ └──┘ └──┘ └──┘ └──┘ └──┘
src └─┘└────┘ └──┘ └──┘ └──┘ └──┘ └──┘
typ └─┘└────┘ └──┘ └──┘ └──┘ └──┘ └──┘
1250
1251 protected theorem encode : ∀ {n}, @primrec' n encode
id ┴┴ └──────┘ ┴ └────┘
src └──────┘ └────┘
typ ┴┴ └──────┘ ┴ └────┘
doc └──────┘
1252 | 0 := (const 0).of_eq (λ v, by rw v.eq_nil; refl)
id └───┘ └───┘ ┴
src └───┘ └───┘ └─┘ └──┘
typ └───┘ └───┘ ┴ └─┘└──────┘ └──┘
doc └─┘ └──┘
txt └─┘ └──┘
par └─┘ └──┘
pid ┴
st └────────────────┘
1253 | (n+1) := (succ.comp₁ _ (mkpair.comp₂ _ head (tail encode)))
id ┴ └──┘└────┘ └────┘└────┘ └──┘ └──┘ └────┘
src ┴ └──┘└────┘ └────┘└────┘ └──┘ └──┘
typ ┴ └──┘└────┘ └────┘└────┘ └──┘ └──┘ └────┘
1254 .of_eq $ λ ⟨a::l, e⟩, rfl
id └───┘ ┴ └┘ └─┘
src └───┘ └┘ └─┘
typ └───┘ ┴ └┘ └─┘
1255
1256 theorem sqrt : @primrec' 1 (λ v, v.head.sqrt) :=
id └──────┘ ┴ ┴└───┘└───┘
src └──────┘ └───┘└───┘
typ └──────┘ ┴ ┴└───┘└───┘
doc └──────┘ └───┘
1257 begin
st └─────
1258 suffices H : ∀ n : ℕ, n.sqrt = n.elim 0 (λ x y,
id └───┘ ┴ └───┘
src └───────────┘ └───┘ ┴ └───┘┴┴┴ └───┘└─┘ └─────
typ └───────────┘ └───┘ ┴ └───┘┴┴┴ └───┘└─┘ └─────
doc └───────────┘ └───┘ ┴ └───┘┴ ┴ └─┘ └─────
txt └───────────┘ └───┘ ┴ ┴ ┴ └─┘ └─────
par └───────────┘ └───┘ ┴ ┴ ┴ └─┘ └─────
pid └────────┘└─┘ └───┘ ┴ ┴ ┴ └─┘ └─────
st ──────────────────────────────────────────────────
1259 if x.succ < y.succ*y.succ then y else y.succ),
id ┴ └───┘┴
src ───┘ └──────┘┴┴ └───┘┴ └────┘ └────┘ ┴
typ ───┘ └──────┘┴┴ └───┘┴ └────┘ └────┘ ┴
doc ───┘ └──────┘ ┴ └────┘ └────┘ ┴
txt ───┘ └──────┘ ┴ └────┘ └────┘ ┴
par ───┘ └──────┘ ┴ └────┘ └────┘ ┴
pid ───┘ └──────┘ ┴ └────┘ └────┘ ┴
st ────────────────────────────────────────────────┘└─
1260 { simp [H],
id ┴
src └────┘ ┴
typ └────┘┴┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴┴ ┴
st ───┘└──────┘└─
1261 have := @prec' 1 _ _ (λ v,
id └───┘
src └──────┘ └───┘└─────┘ └───
typ └──────┘ └───┘└─────┘ └───
doc └──────┘ └─────┘ └───
txt └──────┘ └─────┘ └───
par └──────┘ └─────┘ └───
pid └───┘└─┘ └─────┘ └───
st ───────────────────────────────
1262 by have x := v.head; have y := v.tail.head; from
id └────┘ └─────────┘
src ─────┘ └─────────┘└────┘└──────────┘└─────────┘└┘└────
typ ─────┘ └─────────┘└────┘└──────────┘└─────────┘└┘└────
doc ─────┘ └─────────┘ └──────────┘ └┘└────
txt ─────┘ └─────────┘ └──────────┘ └┘└────
par ─────┘ └─────────┘ └──────────┘ └┘└────
pid ─────┘ └─────────┘ └──────────┘ └──────
st ───────┘└──────────────────────────────────────────────
1263 if x.succ < y.succ*y.succ then y else y.succ) head (const 0) _,
id └────┘ └──┘ └───┘
src ─────┘ └──────┘ ┴ └────┘ └────┘└────┘└┘└──┘┴ └───┘└───┘
typ ─────┘ └──────┘ ┴ └────┘ └────┘└────┘└┘└──┘┴ └───┘└───┘
doc ─────┘ └──────┘ ┴ └────┘ └────┘ └┘ ┴ └───┘
txt ─────┘ └──────┘ ┴ └────┘ └────┘ └┘ ┴ └───┘
par ─────┘ └──────┘ ┴ └────┘ └────┘ └┘ ┴ └───┘
pid ─────┘ └──────┘ ┴ └────┘ └────┘ └┘ ┴ └───┘
st ─────────────────────────────────────────────────┘└────────────────┘└─
1264 { convert this, funext, congr, funext x y, congr; simp },
id └──┘
src └──────┘ └────┘ └───┘ └────────┘ └───┘ └───┘
typ └──────┘└──┘ └────┘ └───┘ └────────┘ └───┘ └───┘
doc └──────┘ └────┘ └────────┘ └───┘
txt └──────┘ └────┘ └───┘ └────────┘ └───┘ └───┘
par └──────┘ └────┘ └───┘ └────────┘ └───┘ └───┘
pid ┴ └──┘ ┴
st ─────┘└──────────┘└──────┘└─────┘└──────────┘└────────────┘└┘└
1265 have x1 := succ.comp₁ _ head,
id └────────┘ └──┘
src └─────────┘└────────┘└─┘└──┘
typ └─────────┘└────────┘└─┘└──┘
doc └─────────┘ └─┘
txt └─────────┘ └─┘
par └─────────┘ └─┘
pid └─────┘┴└─┘ └─┘
st ───────────────────────────────┘└─
1266 have y1 := succ.comp₁ _ (tail head),
id └────────┘ └──┘ └──┘
src └─────────┘└────────┘└─┘ └──┘┴└──┘┴
typ └─────────┘└────────┘└─┘ └──┘┴└──┘┴
doc └─────────┘ └─┘ ┴ ┴
txt └─────────┘ └─┘ ┴ ┴
par └─────────┘ └─┘ ┴ ┴
pid └─────┘┴└─┘ └─┘ ┴ ┴
st ──────────────────────────────────────┘└─
1267 exact if_lt x1 (mul.comp₂ _ y1 y1) (tail head) y1 },
id └───┘ └┘ └───────┘ └──┘ └──┘ └┘
src └────┘└───┘┴ ┴ └───────┘└─┘ ┴ └┘ └──┘┴└──┘└┘ ┴
typ └────┘└───┘┴└┘┴ └───────┘└─┘ ┴ └┘ └──┘┴└──┘└┘└┘┴
doc └────┘ ┴ ┴ └─┘ ┴ └┘ ┴ └┘ ┴
txt └────┘ ┴ ┴ └─┘ ┴ └┘ ┴ └┘ ┴
par └────┘ ┴ ┴ └─┘ ┴ └┘ ┴ └┘ ┴
pid ┴ ┴ ┴ └─┘ ┴ └┘ ┴ └┘ ┴
st ─────────────────────────────────────────────────────┘└┘└
1268 intro, symmetry,
src └───┘ └──────┘
typ └───┘ └──────┘
doc └───┘ └──────┘
txt └───┘ └──────┘
par └───┘ └──────┘
st ──────┘└────────┘└─
1269 induction n with n IH, {refl},
id ┴
src └────────┘ └────────┘ └──┘
typ └────────┘┴└────────┘ └──┘
doc └────────┘ └────────┘ └──┘
txt └────────┘ └────────┘ └──┘
par └────────┘ └────────┘ └──┘
pid ┴ ┴└───────┘
st ──────────────────────┘└─────┘└┘└
1270 dsimp, rw IH, split_ifs,
id └┘
src └───┘ └─┘ └───────┘
typ └───┘ └─┘└┘ └───────┘
doc └───┘ └─┘ └───────┘
txt └───┘ └─┘ └───────┘
par └───┘ └─┘ └───────┘
pid ┴
st ──────┘└─────┘└─────────┘└─
1271 { exact le_antisymm (nat.sqrt_le_sqrt (nat.le_succ _))
id └─────────┘ └──────────────┘ └─────────┘
src └────┘└─────────┘┴ └──────────────┘┴ └─────────┘└────
typ └────┘└─────────┘┴ └──────────────┘┴ └─────────┘└────
doc └────┘ ┴ ┴ └────
txt └────┘ ┴ ┴ └────
par └────┘ ┴ ┴ └────
pid ┴ ┴ ┴ └────
st ───┘└────────────────────────────────────────────────────
1272 (nat.lt_succ_iff.1 $ nat.sqrt_lt.2 h) },
id └─────────────┘ └─────────┘ ┴
src ─────┘ └─────────────┘└─┘ ┴└─────────┘└─┘ └┘
typ ─────┘ └─────────────┘└─┘ ┴└─────────┘└─┘┴└┘
doc ─────┘ └─┘ ┴ └─┘ └┘
txt ─────┘ └─┘ ┴ └─┘ └┘
par ─────┘ └─┘ ┴ └─┘ └┘
pid ─────┘ └─┘ ┴ └─┘ ┴┴
st ───────────────────────────────────────────┘└┘└
1273 { exact nat.eq_sqrt.2 ⟨not_lt.1 h, nat.sqrt_lt.1 $
id └─────────┘ └────┘ ┴ └─────────┘
src └────┘└─────────┘└─┘ └────┘└─┘ └┘└─────────┘└─┘ └
typ └────┘└─────────┘└─┘ └────┘└─┘┴└┘└─────────┘└─┘ └
doc └────┘ └─┘ └─┘ └┘ └─┘ └
txt └────┘ └─┘ └─┘ └┘ └─┘ └
par └────┘ └─┘ └─┘ └┘ └─┘ └
pid ┴ └─┘ └─┘ └┘ └─┘ └
st ─────────────────────────────────────────────────────
1274 nat.lt_succ_iff.2 $ nat.sqrt_succ_le_succ_sqrt _⟩ },
id └─────────────┘ └────────────────────────┘
src ─────┘└─────────────┘└─┘ ┴└────────────────────────┘└──┘
typ ─────┘└─────────────┘└─┘ ┴└────────────────────────┘└──┘
doc ─────┘ └─┘ ┴ └──┘
txt ─────┘ └─┘ ┴ └──┘
par ─────┘ └─┘ ┴ └──┘
pid ─────┘ └─┘ ┴ └─┘┴
st ───────────────────────────────────────────────────────┘└──
1275 end
st ──┘
1276
1277 theorem unpair₁ {n f} (hf : @primrec' n f) :
id └──────┘ ┴ ┴
src └──────┘
typ └──────┘ ┴ ┴
doc └──────┘
1278 @primrec' n (λ v, (f v).unpair.1) :=
id └──────┘ ┴ ┴ ┴ ┴ └────┘ ┴
src └──────┘ └────┘ ┴
typ └──────┘ ┴ ┴ ┴ ┴ └────┘ ┴
doc └──────┘ └────┘
1279 begin
st └─────
1280 have s := sqrt.comp₁ _ hf,
id └────────┘ └┘
src └────────┘└────────┘└─┘
typ └────────┘└────────┘└─┘└┘
doc └────────┘ └─┘
txt └────────┘ └─┘
par └────────┘ └─┘
pid └────┘┴└─┘ └─┘
st ──────────────────────────┘└─
1281 have fss := sub.comp₂ _ hf (mul.comp₂ _ s s),
id └───────┘ └┘ └───────┘ ┴
src └──────────┘└───────┘└─┘ ┴ └───────┘└─┘ ┴ ┴
typ └──────────┘└───────┘└─┘└┘┴ └───────┘└─┘ ┴┴┴
doc └──────────┘ └─┘ ┴ └─┘ ┴ ┴
txt └──────────┘ └─┘ ┴ └─┘ ┴ ┴
par └──────────┘ └─┘ ┴ └─┘ ┴ ┴
pid └──────┘┴└─┘ └─┘ ┴ └─┘ ┴ ┴
st ─────────────────────────────────────────────┘└─
1282 refine (if_lt fss s fss s).of_eq (λ v, _),
id └───┘ └─┘ ┴
src └─────┘ └───┘┴ ┴ ┴ ┴ └──────┘ └────┘
typ └─────┘ └───┘┴ ┴ ┴└─┘┴┴└──────┘ └────┘
doc └─────┘ ┴ ┴ ┴ ┴ └──────┘ └────┘
txt └─────┘ ┴ ┴ ┴ ┴ └──────┘ └────┘
par └─────┘ ┴ ┴ ┴ ┴ └──────┘ └────┘
pid ┴ ┴ ┴ ┴ ┴ └──────┘ └────┘
st ──────────────────────────────────────────┘└─
1283 simp [nat.unpair], split_ifs; refl
id └────────┘
src └────┘└────────┘┴ └───────┘ └───┘
typ └────┘└────────┘┴ └───────┘ └───┘
doc └────┘└────────┘┴ └───────┘ └───┘
txt └────┘ ┴ └───────┘ └───┘
par └────┘ ┴ └───────┘ └───┘
pid ┴┴ ┴ ┴
st ──────────────────┘└────────────────┘
1284 end
st └─┘
1285
1286 theorem unpair₂ {n f} (hf : @primrec' n f) :
id └──────┘ ┴ ┴
src └──────┘
typ └──────┘ ┴ ┴
doc └──────┘
1287 @primrec' n (λ v, (f v).unpair.2) :=
id └──────┘ ┴ ┴ ┴ ┴ └────┘ ┴
src └──────┘ └────┘ ┴
typ └──────┘ ┴ ┴ ┴ ┴ └────┘ ┴
doc └──────┘ └────┘
1288 begin
st └─────
1289 have s := sqrt.comp₁ _ hf,
id └────────┘ └┘
src └────────┘└────────┘└─┘
typ └────────┘└────────┘└─┘└┘
doc └────────┘ └─┘
txt └────────┘ └─┘
par └────────┘ └─┘
pid └────┘┴└─┘ └─┘
st ──────────────────────────┘└─
1290 have fss := sub.comp₂ _ hf (mul.comp₂ _ s s),
id └───────┘ └┘ └───────┘ ┴
src └──────────┘└───────┘└─┘ ┴ └───────┘└─┘ ┴ ┴
typ └──────────┘└───────┘└─┘└┘┴ └───────┘└─┘ ┴┴┴
doc └──────────┘ └─┘ ┴ └─┘ ┴ ┴
txt └──────────┘ └─┘ ┴ └─┘ ┴ ┴
par └──────────┘ └─┘ ┴ └─┘ ┴ ┴
pid └──────┘┴└─┘ └─┘ ┴ └─┘ ┴ ┴
st ─────────────────────────────────────────────┘└─
1291 refine (if_lt fss s s (sub.comp₂ _ fss s)).of_eq (λ v, _),
id └───┘ └───────┘ └─┘ ┴
src └─────┘ └───┘┴ ┴ ┴ ┴ └───────┘└─┘ ┴ └───────┘ └────┘
typ └─────┘ └───┘┴ ┴ ┴ ┴ └───────┘└─┘└─┘┴┴└───────┘ └────┘
doc └─────┘ ┴ ┴ ┴ ┴ └─┘ ┴ └───────┘ └────┘
txt └─────┘ ┴ ┴ ┴ ┴ └─┘ ┴ └───────┘ └────┘
par └─────┘ ┴ ┴ ┴ ┴ └─┘ ┴ └───────┘ └────┘
pid ┴ ┴ ┴ ┴ ┴ └─┘ ┴ └───────┘ └────┘
st ──────────────────────────────────────────────────────────┘└─
1292 simp [nat.unpair], split_ifs; refl
id └────────┘
src └────┘└────────┘┴ └───────┘ └───┘
typ └────┘└────────┘┴ └───────┘ └───┘
doc └────┘└────────┘┴ └───────┘ └───┘
txt └────┘ ┴ └───────┘ └───┘
par └────┘ ┴ └───────┘ └───┘
pid ┴┴ ┴ ┴
st ──────────────────┘└────────────────┘
1293 end
st └─┘
1294
1295 theorem of_prim : ∀ {n f}, primrec f → @primrec' n f :=
id ┴ ┴ └─────┘ ┴ └──────┘ ┴ ┴
src └─────┘ └──────┘
typ ┴ ┴ └─────┘ ┴ └──────┘ ┴ ┴
doc └─────┘ └──────┘
1296 suffices ∀ f, nat.primrec f → @primrec' 1 (λ v, f v.head), from
id ┴ └─────────┘ ┴ └──────┘ ┴ ┴ ┴└───┘
src └─────────┘ └──────┘ └───┘
typ ┴ └─────────┘ ┴ └──────┘ ┴ ┴ ┴└───┘
doc └─────────┘ └──────┘
1297 λ n f hf, (pred.comp₁ _ $ (this _ hf).comp₁
id ┴ ┴ └┘ └──┘└────┘ └──┘ └┘ └───┘
src └──┘└────┘ └───┘
typ ┴ ┴ └┘ └──┘└────┘ └──┘ └┘ └───┘
1298 (λ m, encodable.encode $ (decode (vector ℕ n) m).map f)
id ┴ └──────────────┘ └────┘ └────┘ ┴ ┴ ┴ └─┘ ┴
src └──────────────┘ └────┘ └────┘ ┴ └─┘
typ ┴ └──────────────┘ └────┘ └────┘ ┴ ┴ ┴ └─┘ ┴
1299 primrec'.encode).of_eq (λ i, by simp [encodek]),
id └─────────────┘ └───┘ ┴ └─────┘
src └─────────────┘ └───┘ └────┘└─────┘┴
typ └─────────────┘ └───┘ ┴ └────┘└─────┘┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴┴ ┴
st └─────────────┘
1300 λ f hf, begin
id ┴ └┘
typ ┴ └┘
st └─────
1301 induction hf,
id └┘
src └────────┘
typ └────────┘└┘
doc └────────┘
txt └────────┘
par └────────┘
pid ┴
st ─────────────┘└─
1302 case nat.primrec.zero { exact const 0 },
id └───┘
src └──────────────────────┘└────┘└───┘└─┘┴
typ └──────────────────────┘└────┘└───┘└─┘┴
doc └──────────────────────┘└────┘ └─┘┴
txt └──────────────────────┘└────┘ └─┘┴
par └──────────────────────┘└────┘ └─┘┴
pid └───────────────┘┴└──────┘ └──┘
st ────────────────────────┘└─────────────┘└┘└
1303 case nat.primrec.succ { exact succ },
id └──┘
src └──────────────────────┘└────┘└──┘┴┴
typ └──────────────────────┘└────┘└──┘┴┴
doc └──────────────────────┘└────┘ ┴┴
txt └──────────────────────┘└────┘ ┴┴
par └──────────────────────┘└────┘ ┴┴
pid └───────────────┘┴└──────┘ └┘
st ────────────────────────┘└──────────┘└┘└
1304 case nat.primrec.left { exact unpair₁ head },
id └─────┘ └──┘
src └──────────────────────┘└────┘└─────┘┴└──┘┴┴
typ └──────────────────────┘└────┘└─────┘┴└──┘┴┴
doc └──────────────────────┘└────┘ ┴ ┴┴
txt └──────────────────────┘└────┘ ┴ ┴┴
par └──────────────────────┘└────┘ ┴ ┴┴
pid └───────────────┘┴└──────┘ ┴ └┘
st ────────────────────────┘└──────────────────┘└┘└
1305 case nat.primrec.right { exact unpair₂ head },
id └─────┘ └──┘
src └───────────────────────┘└────┘└─────┘┴└──┘┴┴
typ └───────────────────────┘└────┘└─────┘┴└──┘┴┴
doc └───────────────────────┘└────┘ ┴ ┴┴
txt └───────────────────────┘└────┘ ┴ ┴┴
par └───────────────────────┘└────┘ ┴ ┴┴
pid └────────────────┘┴└──────┘ ┴ └┘
st ─────────────────────────┘└──────────────────┘└┘└
1306 case nat.primrec.pair : f g _ _ hf hg {
src └───────────────────────────────────────
typ └───────────────────────────────────────
doc └───────────────────────────────────────
txt └───────────────────────────────────────
par └───────────────────────────────────────
pid └───────────────┘└──────────────┘└──
st ────────────────────────────────────────┘└
1307 exact mkpair.comp₂ _ hf hg },
id └──────────┘ └┘ └┘
src ───┘└────┘└──────────┘└─┘ ┴ ┴┴
typ ───┘└────┘└──────────┘└─┘└┘┴└┘┴┴
doc ───┘└────┘ └─┘ ┴ ┴┴
txt ───┘└────┘ └─┘ ┴ ┴┴
par ───┘└────┘ └─┘ ┴ ┴┴
pid ─────────┘ └─┘ ┴ └┘
st ──────────────────────────────┘└┘└
1308 case nat.primrec.comp : f g _ _ hf hg {
src └───────────────────────────────────────
typ └───────────────────────────────────────
doc └───────────────────────────────────────
txt └───────────────────────────────────────
par └───────────────────────────────────────
pid └───────────────┘└──────────────┘└──
st ────────────────────────────────────────┘└
1309 exact hf.comp₁ _ hg },
id └──────┘ └┘
src ───┘└────┘└──────┘└─┘ ┴┴
typ ───┘└────┘└──────┘└─┘└┘┴┴
doc ───┘└────┘ └─┘ ┴┴
txt ───┘└────┘ └─┘ ┴┴
par ───┘└────┘ └─┘ ┴┴
pid ─────────┘ └─┘ └┘
st ───────────────────────┘└┘└
1310 case nat.primrec.prec : f g _ _ hf hg {
src └───────────────────────────────────────
typ └───────────────────────────────────────
doc └───────────────────────────────────────
txt └───────────────────────────────────────
par └───────────────────────────────────────
pid └───────────────┘└──────────────┘└──
st ────────────────────────────────────────┘└
1311 simpa using prec' (unpair₂ head)
id └───┘ └─────┘
src ───┘└──────────┘└───┘┴ └─────┘┴ └─
typ ───┘└──────────┘└───┘┴ └─────┘┴ └─
doc ───┘└──────────┘ ┴ ┴ └─
txt ───┘└──────────┘ ┴ ┴ └─
par ───┘└──────────┘ ┴ ┴ └─
pid ───────────────┘ ┴ ┴ └─
st ─────────────────────────────────────
1312 (hf.comp₁ _ (unpair₁ head))
id └──────┘
src ─────┘ └──────┘└─┘ ┴ └──
typ ─────┘ └──────┘└─┘ ┴ └──
doc ─────┘ └─┘ ┴ └──
txt ─────┘ └─┘ ┴ └──
par ─────┘ └─┘ ┴ └──
pid ─────┘ └─┘ ┴ └──
st ──────────────────────────────────
1313 (hg.comp₁ _ $ mkpair.comp₂ _ (unpair₁ $ tail $ tail head)
id └──────┘ └─────┘
src ─────┘ └──────┘└─┘ ┴ └─┘ └─────┘┴ ┴ ┴ ┴ ┴ └─
typ ─────┘ └──────┘└─┘ ┴ └─┘ └─────┘┴ ┴ ┴ ┴ ┴ └─
doc ─────┘ └─┘ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ └─
txt ─────┘ └─┘ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ └─
par ─────┘ └─┘ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ └─
pid ─────┘ └─┘ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ └─
st ────────────────────────────────────────────────────────────────
1314 (mkpair.comp₂ _ head (tail head))) },
id └──────────┘ └──┘ └──┘
src ───────┘ └──────────┘└─┘ ┴ └──┘┴└──┘└──┘┴
typ ───────┘ └──────────┘└─┘ ┴ └──┘┴└──┘└──┘┴
doc ───────┘ └─┘ ┴ ┴ └──┘┴
txt ───────┘ └─┘ ┴ ┴ └──┘┴
par ───────┘ └─┘ ┴ ┴ └──┘┴
pid ───────┘ └─┘ ┴ ┴ └───┘
st ──────────────────────────────────────────┘└──
1315 end
st ──┘
1316
1317 theorem prim_iff {n f} : @primrec' n f ↔ primrec f := ⟨to_prim, of_prim⟩
id └──────┘ ┴ ┴ ┴ └─────┘ ┴ └─────┘ └─────┘
src └──────┘ ┴ └─────┘ └─────┘ └─────┘
typ └──────┘ ┴ ┴ ┴ └─────┘ ┴ └─────┘ └─────┘
doc └──────┘ └─────┘
1318
1319 theorem prim_iff₁ {f : ℕ → ℕ} :
id ┴ ┴
src ┴ ┴
typ ┴ ┴
1320 @primrec' 1 (λ v, f v.head) ↔ primrec f :=
id └──────┘ ┴ ┴ ┴└───┘ ┴ └─────┘ ┴
src └──────┘ └───┘ ┴ └─────┘
typ └──────┘ ┴ ┴ ┴└───┘ ┴ └─────┘ ┴
doc └──────┘ └─────┘
1321 prim_iff.trans ⟨
id └──────┘└────┘
src └──────┘└────┘
typ └──────┘└────┘
1322 λ h, (h.comp $ vector_of_fn $ λ i, primrec.id).of_eq (λ v, by simp),
id ┴ ┴└───┘ └──────────┘ ┴ └────────┘ └───┘ ┴
src └───┘ └──────────┘ └────────┘ └───┘ └──┘
typ ┴ ┴└───┘ └──────────┘ ┴ └────────┘ └───┘ ┴ └──┘
doc └──┘
txt └──┘
par └──┘
st └───┘
1323 λ h, h.comp vector_head⟩
id ┴ ┴└───┘ └─────────┘
src └───┘ └─────────┘
typ ┴ ┴└───┘ └─────────┘
1324
1325 theorem prim_iff₂ {f : ℕ → ℕ → ℕ} :
id ┴ ┴ ┴
src ┴ ┴ ┴
typ ┴ ┴ ┴
1326 @primrec' 2 (λ v, f v.head v.tail.head) ↔ primrec₂ f :=
id └──────┘ ┴ ┴ ┴└───┘ ┴└───┘└───┘ ┴ └──────┘ ┴
src └──────┘ └───┘ └───┘└───┘ ┴ └──────┘
typ └──────┘ ┴ ┴ ┴└───┘ ┴└───┘└───┘ ┴ └──────┘ ┴
doc └──────┘ └──────┘
1327 prim_iff.trans ⟨
id └──────┘└────┘
src └──────┘└────┘
typ └──────┘└────┘
1328 λ h, (h.comp $ vector_cons.comp fst $
id ┴ ┴└───┘ └─────────┘└───┘ └─┘
src └───┘ └─────────┘└───┘ └─┘
typ ┴ ┴└───┘ └─────────┘└───┘ └─┘
1329 vector_cons.comp snd (primrec.const nil)).of_eq (λ v, by simp),
id └─────────┘└───┘ └─┘ └───────────┘ └─┘ └───┘ ┴
src └─────────┘└───┘ └─┘ └───────────┘ └─┘ └───┘ └──┘
typ └─────────┘└───┘ └─┘ └───────────┘ └─┘ └───┘ ┴ └──┘
doc └──┘
txt └──┘
par └──┘
st └───┘
1330 λ h, h.comp vector_head (vector_head.comp vector_tail)⟩
id ┴ ┴└───┘ └─────────┘ └─────────┘└───┘ └─────────┘
src └───┘ └─────────┘ └─────────┘└───┘ └─────────┘
typ ┴ ┴└───┘ └─────────┘ └─────────┘└───┘ └─────────┘
1331
1332 theorem vec_iff {m n f} :
1333 @vec m n f ↔ primrec f :=
id └─┘ ┴ ┴ ┴ ┴ └─────┘ ┴
src └─┘ ┴ └─────┘
typ └─┘ ┴ ┴ ┴ ┴ └─────┘ ┴
doc └─────┘
1334 ⟨λ h, by simpa using vector_of_fn (λ i, to_prim (h i)),
id ┴ └──────────┘ └─────┘ ┴
src └──────────┘└──────────┘┴ └──┘└─────┘┴ ┴ └┘
typ ┴ └──────────┘└──────────┘┴ └──┘└─────┘┴ ┴┴ └┘
doc └──────────┘ ┴ └──┘ ┴ ┴ └┘
txt └──────────┘ ┴ └──┘ ┴ ┴ └┘
par └──────────┘ ┴ └──┘ ┴ ┴ └┘
pid ┴└────┘ ┴ └──┘ ┴ ┴ └┘
st └────────────────────────────────────────────┘
1335 λ h i, of_prim $ vector_nth.comp h (primrec.const i)⟩
id ┴ ┴ └─────┘ └────────┘└───┘ ┴ └───────────┘ ┴
src └─────┘ └────────┘└───┘ └───────────┘
typ ┴ ┴ └─────┘ └────────┘└───┘ ┴ └───────────┘ ┴
1336
1337 end nat.primrec'
1338
1339 theorem primrec.nat_sqrt : primrec nat.sqrt :=
id └─────┘ └──────┘
src └─────┘ └──────┘
typ └─────┘ └──────┘
doc └─────┘ └──────┘
1340 nat.primrec'.prim_iff₁.1 nat.primrec'.sqrt
id └────────────────────┘┴ └───────────────┘
src └────────────────────┘┴ └───────────────┘
typ └────────────────────┘┴ └───────────────┘